Zipper
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
接着进行搜索大练习,这段时间是DFS的练习,基本做的都是DFS的题目,这道题,挺不错的,虽然是基本的DFS,但也用到了记忆化搜索,如果不用的话,一定会超时的哟╮(╯▽╰)╭。
刚开始做的时候,没仔细看题,结果纠结好长时间,题目中已经描述了,串一加上串二的长度一定等于串三的长度,
也就是说串三上的内容一定会显现在其他两个串上。
这其实就省却了好多麻烦。
比如,当我们判断当前进来的两个位置,和串三相应位置比较,要么串三与串一相同,要么与串二相同,如果两个都不相同,那就不需要处理了,直接return掉。
最后判断是否能构成时,只需要判断最后的(我用的string来存储,最后为'\0'),三个串末尾是否都已经到达\0,即可。
还有,剪枝不一定是越多越好,因为每一次判断都需要消耗时间,所以剪枝要看性价比。
恩,就是这样,喵~
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
bool ispos;
int vis[301][301];
string str1,str2,str;
void dfs(int s1,int s2,int s)
{
// 相关一系列剪枝与判断
if(str[s]=='\0' && str1[s1]=='\0' && str2[s2]=='\0') {ispos=1;return;}
if(str[s]!=str1[s1] && str[s]!=str2[s2]) return;
if(ispos) return;
if(vis[s1][s2]) return;
vis[s1][s2]=1;
if(str1[s1]==str[s]) dfs(s1+1,s2,s+1);
if(str2[s2]==str[s]) dfs(s1,s2+1,s+1);
}
int main()
{
int n,num;
cin>>n;
for(num=1;num<=n;++num)
{
cin>>str1>>str2>>str;
memset(vis,0,sizeof(vis));
ispos=false;
dfs(0,0,0);
if(!ispos) cout<<"Data set "<<num<<": no"<<endl;
else cout<<"Data set "<<num<<": yes"<<endl;
}
return 0;
}