解题报告:
设:A=a0a1a2...an-1,其中前缀串Ai=a0a1a2...ai(i>=0,i<=n-1);
B=b0b1b2...bn-1,其中前缀串Bj=b0b1..bj(0<=j>=m-1);
C=c0c1c2..cn-1,其中前缀串Ck=c0c1c2..ci(k>=0,k<=n+m-1);
can[i][j]为Ai-1(A 中长度为i的前缀串),和Bj成功组成Ci+j-1(C中长度为i+j的前缀串)的标志,can[0][0]=1;
当i>=1且ci+j-1=ai-1时,需要看Ai-2和Bj-1能否成功组成ci+j-2,即
can[i][j]=can[i][j]||can[i-1][j];
当j>=1且ci+j-1=bj-1时,需要看ai-1和bj-2能否组成ci+j-2,即
can[i][j]=can[i][j]||can[i][j-1];
最后can[n][m]就是最后结果。
代码:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
int t,i,j,n,m;
char a[210],b[210],c[420];
cin>>t;
int k;
int can[210][210];
for(k=1;k<=t;k++)
{
cin>>a>>b>>c;
n=strlen(a);
m=strlen(b);
cout<<"Data set "<<k;
int i1=0,j1=0;
memset(can,0,sizeof(can));
can[0][0]=1;
for(i=0;i<=n;i++)
{
for(j=0;j<=m;j++)
{
if(i>=1&&a[i-1]==c[i+j-1])
can[i][j]=can[i][j]||can[i-1][j];
if(j>=1&&b[j-1]==c[i+j-1])
can[i][j]=can[i][j]||can[i][j-1];
}
}
if(can[n][m])
cout<<": yes"<<endl;
else
cout<<": no"<<endl;
}
return 0;
}