hdoj 1501 Zipper

来源:互联网 发布:社交网络上的跟风行为 编辑:程序博客网 时间:2024/06/05 12:04

原题:
Zipper
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 8561 Accepted Submission(s): 3020

Problem Description
Given three strings, you are to determine whether the third string can be formed by combining the characters in the first two strings. The first two strings can be mixed arbitrarily, but each must stay in its original order.

For example, consider forming “tcraete” from “cat” and “tree”:

String A: cat
String B: tree
String C: tcraete

As you can see, we can form the third string by alternating characters from the two strings. As a second example, consider forming “catrtee” from “cat” and “tree”:

String A: cat
String B: tree
String C: catrtee

Finally, notice that it is impossible to form “cttaree” from “cat” and “tree”.

Input
The first line of input contains a single positive integer from 1 through 1000. It represents the number of data sets to follow. The processing for each data set is identical. The data sets appear on the following lines, one data set per line.

For each data set, the line of input consists of three strings, separated by a single space. All strings are composed of upper and lower case letters only. The length of the third string is always the sum of the lengths of the first two strings. The first two strings will have lengths between 1 and 200 characters, inclusive.

Output
For each data set, print:

Data set n: yes

if the third string can be formed from the first two, or

Data set n: no

if it cannot. Of course n should be replaced by the data set number. See the sample output below for an example.

Sample Input

3
cat tree tcraete
cat tree catrtee
cat tree cttaree

Sample Output

Data set 1: yes
Data set 2: yes
Data set 3: no
题目大意:
问给你前两个字符串,能不能正好组成第三个字符串。
代码:

#include <iostream>#include <string>#include <cstring>#include <cstdio>using namespace std;int dp[205][205];string s1,s2,s3;int l1,l2,l3;bool dfs(int x,int y){    if(x+y==l3)     return true;     if(dp[x][y]>0)        return false;     dp[x][y]=1;    if(x<l1&&s1[x]==s3[x+y]&&dfs(x+1,y))        return true;    if(y<l2&&s2[y]==s3[x+y]&&dfs(x,y+1))        return true;    return false;}int main(){    ios::sync_with_stdio(false);    int ans,n;    cin>>n;    for(int x=1;x<=n;x++)    {        memset(dp,0,sizeof(dp));        cin>>s1>>s2>>s3;        l1=s1.size();l2=s2.size();l3=s3.size();        if(l1+l2!=l3)        {            cout<<"Data set "<<x<<": no"<<endl;            continue;        }        if(dfs(0,0))            cout<<"Data set "<<x<<": yes"<<endl;         else            cout<<"Data set "<<x<<": no"<<endl;    }    return 0;}

思路:
之前拿爬虫爬航电上的题目数,发现我没过的题目里面有这一道题。貌似当年在poj上做过,不过当时没做出来,看的别人的题解。看一眼瞬间明白啦=_=。差不多隔了能有一年多,这道题重新拿出来做了一遍,哎,不是wa就是tle。首先,很明显,如果用dp的话就是两个状态,第三个字符串的字母要么来自第一个,要么来自第二个。转移方程可以写成这样dp[i++][j]=1(s1[i]==s3[i+j]),dp[i][j++]=1(s2[j]==s3[i+j])
可以用记忆考虑用记忆化搜索来解答,注意dp[i][j]如果之前判断过要减枝剪掉,否则tle。

0 0
原创粉丝点击