比赛描述
已知有两个字串 A$, B$ 及一组字串变换的规则(至多6个规则):
A1$ -> B1$
A2$ -> B2$
规则的含义为:在 A$中的子串 A1$ 可以变换为 B1$、A2$ 可以变换为 B2$ …。
例如:A$='abcd' B$='xyz'
变换规则为:
'abc'->'xu' 'ud'->'y' 'y'->'yz'
则此时,A$ 可以经过一系列的变换变为 B$,其变换的过程为:
'abcd'->'xud'->'xy'->'xyz'
共进行了三次变换,使得 A$ 变换为B$。
输入
键盘输人文件名。文件格式如下:
A$ B$
A1$ B1$ \
A2$ B2$ |-> 变换规则
... ... /
所有字符串长度的上限为 20。
输出
输出至屏幕。格式如下:
若在 10 步(包含 10步)以内能将 A$ 变换为 B$,则输出最少的变换步数;否则输出"NO ANSWER!"
样例输入
abcd wyz
abc xu
ud y
y yz
样例输出
3
题目来源
NUPT
/* Time Limit Exceed at Test 4 #include<iostream> #include<string> using namespace std; #define MAX_STEP 10 int step,len; string A,B,a[6],b[6]; void dfs(string A,int cs){ if(cs>step || cs>MAX_STEP){ return; } int i,j,temp; string s; for(i=0;i<(int)A.length();i++){ temp = (int)A.size()-i; for(j=0;j<len;j++){ if(temp>=(int)a[j].length()){ s = A.substr(i,a[j].size()); if(s==a[j]){ s = A.substr(0,i)+b[j]+A.substr(i+a[j].size(),A.size()-i-a[j].size()); if(s==B){ step = cs; }else{ dfs(s,cs+1); } } } } } } int main(){ // freopen("test.txt","r",stdin); cin>>A>>B; step = INT_MAX; len = 0; while(cin>>a[len]>>b[len]){ len++; } dfs(A,1); if(step!=INT_MAX){ printf("%d\n",step); }else{ printf("NO ANSWER!\n"); } } */ /* 3MS #include<iostream> using namespace std; struct node{ char s[30]; int dep; } list1[5010],list2[5010]; char a[7][30],b[7][30]; int n; bool check(char *s1,char *s2){ int len1=strlen(s1),len2=strlen(s2); if (len1!=len2) return false; for (int i=0;i<strlen(s1);i++) if (s1[i]!=s2[i]) return false; return true; } bool pan1(char *s,int i,int x){ int len=strlen(a[x]); for (int j=i;j<i+len;j++) if (s[j]!=a[x][j-i]) return false; return true; } bool pan2(char *s,int i,int x){ int len=strlen(b[x]); for (int j=i;j<i+len;j++) if (s[j]!=b[x][j-i]) return false; return true; } void bfs(){ int head1,tail1,head2,tail2,i,j,k,l; head1=tail1=head2=tail2=1; while(head1<=tail1 && head2<=tail2){ if(list1[head1].dep+list2[head2].dep>10){ printf("NO ANSWER!\n"); return ; } int len1=strlen(list1[head1].s); for( i=0;i<len1;i++){ for( j=1;j<=n;j++){ if(pan1(list1[head1].s,i,j)){ tail1++; for(k=0;k<i;k++){ list1[tail1].s[k]=list1[head1].s[k]; } int len2=strlen(b[j]); for(l=0;l<len2;l++,k++){ list1[tail1].s[k]=b[j][l]; } len2=strlen(list1[head1].s); for(l=i+strlen(a[j]);l<=len2;l++,k++){ list1[tail1].s[k]=list1[head1].s[l]; } list1[tail1].s[k]='\0'; list1[tail1].dep=list1[head1].dep+1; for (k=1;k<=tail2;k++){ if (check(list1[tail1].s,list2[k].s)){ printf("%d\n",list1[tail1].dep+list2[k].dep); return ; } } } } } len1=strlen(list2[head2].s); for(i=0;i<len1;i++){ for(j=1;j<=n;j++){ if(pan2(list2[head2].s,i,j)){ tail2++; for(k=0;k<i;k++){ list2[tail2].s[k]=list2[head2].s[k]; } int len2=strlen(a[j]); for(l=0;l<len2;l++,k++){ list2[tail2].s[k]=a[j][l]; } len2=strlen(list2[head2].s); for(l=i+strlen(b[j]);l<=len2;l++,k++){ list2[tail2].s[k]=list2[head2].s[l]; } list2[tail2].s[k]='\0'; list2[tail2].dep=list2[head2].dep+1; for (k=1;k<=tail1;k++){ if (check(list1[k].s,list2[tail2].s)) { printf("%d\n",list1[k].dep+list2[tail2].dep); return ; } } } } } head1++; head2++; } printf("NO ANSWER!\n"); } int main(){ scanf("%s%s",list1[1].s,list2[1].s); n=1; while (scanf("%s%s",a[n],b[n])!=EOF) n++; n--; list1[1].dep=list2[1].dep=0; bfs(); return 0; } */ /* Wrong Answer at Test 4 #include<iostream> #define MAX_LEN 30 #define MAX_DEP 10 #define MAX_N 5000 struct queueNode{ char c[MAX_LEN]; int dep; }que[MAX_N]; int qHead,qTail; char a[6][MAX_LEN]; char b[6][MAX_LEN]; char target[MAX_LEN]; int aSize; //c2字符串等于c1前面同等长度的字符串 bool hasSub(char *c1,char *c2){ while(*c2 && *c1==*c2){ c1++; c2++; } if(*c2){ return 0; } return 1; } int main(){ // freopen("test.txt","r",stdin); char *p,*q; int depth,len1,len2,i,j,k,l; scanf("%s%s",que[qTail++].c,target); if(strcmp(que[qHead].c,target)==0){ printf("0\n"); return 0; } while(scanf("%s%s",a[aSize],b[aSize])==2){ aSize++; } while(qHead<=qTail){ depth = que[qHead].dep+1; if(depth>MAX_DEP){ break; } p = que[qHead++].c; len1 = (int)strlen(p); for(i=0;i<len1;i++){ for(j=0;j<aSize;j++){ if(hasSub(p+i,a[j])){ q = que[qTail].c; que[qTail++].dep = depth; for(k=0;k<i;k++){ q[k] = p[k]; //原字符串前面的部分 } len2 = (int)strlen(b[j]); for(l=0;l<len2;l++,k++){ //被替换掉的部分 q[k] = b[j][l]; } len2 = (int)strlen(p); for(l=i+(int)strlen(a[j]);l<len2;l++,k++){ q[k] = p[l]; } q[k] = 0; if(strcmp(q,target)==0){ printf("%d\n",depth); return 0; } } } } } printf("NO ANSWER!\n"); } */ /* // Runtime Error at Test 5 //(ACCESS_VIOLATION) //由于数据范围的原因,单项搜索就不行,必须要双向搜索 #include<iostream> using namespace std; struct node{ char s[300]; int dep; } list1[50100]; char a[7][30],b[7][30],target[30]; int n; bool pan1(char *s,int i,int x){ int len=strlen(a[x]); for (int j=i;j<i+len;j++) if (s[j]!=a[x][j-i]) return false; return true; } void bfs(){ int head1,tail1,i,j,k,l; head1=tail1=1; while(head1<=tail1){ if(list1[head1].dep>10){ printf("NO ANSWER!\n"); return ; } int len1=strlen(list1[head1].s); for( i=0;i<len1;i++){ for( j=1;j<=n;j++){ if(pan1(list1[head1].s,i,j)){ tail1++; for(k=0;k<i;k++){ list1[tail1].s[k]=list1[head1].s[k]; } int len2=strlen(b[j]); for(l=0;l<len2;l++,k++){ list1[tail1].s[k]=b[j][l]; } len2=strlen(list1[head1].s); for(l=i+strlen(a[j]);l<=len2;l++,k++){ list1[tail1].s[k]=list1[head1].s[l]; } list1[tail1].s[k]='\0'; list1[tail1].dep=list1[head1].dep+1; if (strcmp(list1[tail1].s,target)==0){ printf("%d\n",list1[tail1].dep); return ; } } } } head1++; } printf("NO ANSWER!\n"); } int main(){ // freopen("test.txt","r",stdin); scanf("%s%s",list1[1].s,target); n=1; while (scanf("%s%s",a[n],b[n])!=EOF) n++; n--; list1[1].dep=0; bfs(); return 0; } */ /* WA4 #include<iostream> #define MAX_LEN 30 #define MAX_DEP 10 #define MAX_N 5000 struct queueNode{ char c[MAX_LEN]; int dep; }que1[MAX_N],que2[MAX_N]; int head1,tail1,head2,tail2; char a[6][MAX_LEN]; char b[6][MAX_LEN]; int aSize; //c2字符串等于c1前面同等长度的字符串 bool hasSub(char *c1,char *c2){ while(*c2 && *c1==*c2){ c1++; c2++; } if(*c2){ return 0; } return 1; } int main(){ freopen("test.txt","r",stdin); char *p,*q; int depth1,depth2,len1,len2,i,j,k,l; scanf("%s%s",que1[tail1++].c,que2[tail2++].c); if(strcmp(que1[head1].c,que2[head2].c)==0){ printf("0\n"); return 0; } while(scanf("%s%s",a[aSize],b[aSize])==2){ aSize++; } while(head1<=tail1 && head2<=tail2){ depth1 = que1[head1].dep+1; depth2 = que2[head2].dep+1; if(depth1+depth2 > MAX_DEP){ break; } if(tail1-head1 <= tail2-head2){ p = que1[head1++].c; len1 = (int)strlen(p); for(i=0;i<len1;i++){ for(j=0;j<aSize;j++){ if(hasSub(p+i,a[j])){ q = que1[tail1].c; que1[tail1++].dep = depth1; for(k=0;k<i;k++){ q[k] = p[k]; //原字符串前面的部分 } len2 = (int)strlen(b[j]); for(l=0;l<len2;l++,k++){ //被替换掉的部分 q[k] = b[j][l]; } len2 = (int)strlen(p); for(l=i+(int)strlen(a[j]);l<len2;l++,k++){ q[k] = p[l]; } q[k] = 0; for(k=head2;k<tail2;k++){ if(strcmp(q,que2[k].c)==0){ printf("%d\n",depth1+que2[k].dep); return 0; } } } } } } if(tail2-head2 <= tail1-head1){ p = que2[head2++].c; len1 = (int)strlen(p); for(i=0;i<len1;i++){ for(j=0;j<aSize;j++){ if(hasSub(p+i,b[j])){ q = que2[tail2].c; que2[tail2++].dep = depth2; for(k=0;k<i;k++){ q[k] = p[k]; //原字符串前面的部分 } len2 = (int)strlen(a[j]); for(l=0;l<len2;l++,k++){ //被替换掉的部分 q[k] = a[j][l]; } len2 = (int)strlen(p); for(l=i+(int)strlen(b[j]);l<len2;l++,k++){ q[k] = p[l]; } q[k] = 0; for(k=head1;k<tail1;k++){ if(strcmp(q,que1[k].c)==0){ printf("%d\n",depth2+que1[k].dep); return 0; } } } } } } } printf("NO ANSWER!\n"); } */ /* AC 0MS #include<iostream> using namespace std; struct node{ char s[30]; int dep; } list1[5010],list2[5010]; char a[7][30],b[7][30]; int n; bool check(char *s1,char *s2){ while(*s1 && *s2 && *s1==*s2){ s1++; s2++; } if(*s1==0 && *s2==0){ return 1; } return 0; } bool pan1(char *s,int i,int x){ int len=strlen(a[x]); for (int j=i;j<i+len;j++) if (s[j]!=a[x][j-i]) return false; return true; } bool pan2(char *s,int i,int x){ int len=strlen(b[x]); for (int j=i;j<i+len;j++) if (s[j]!=b[x][j-i]) return false; return true; } void bfs(){ int head1,tail1,head2,tail2,i,j,k,l; head1=tail1=head2=tail2=1; while(head1<=tail1 && head2<=tail2){ if(list1[head1].dep+list2[head2].dep>10){ printf("NO ANSWER!\n"); return ; } int len1=strlen(list1[head1].s); for( i=0;i<len1;i++){ for( j=1;j<=n;j++){ if(pan1(list1[head1].s,i,j)){ tail1++; for(k=0;k<i;k++){ list1[tail1].s[k]=list1[head1].s[k]; } int len2=strlen(b[j]); for(l=0;l<len2;l++,k++){ list1[tail1].s[k]=b[j][l]; } len2=strlen(list1[head1].s); for(l=i+strlen(a[j]);l<=len2;l++,k++){ list1[tail1].s[k]=list1[head1].s[l]; } list1[tail1].s[k]='\0'; list1[tail1].dep=list1[head1].dep+1; for (k=1;k<=tail2;k++){ if (check(list1[tail1].s,list2[k].s)){ printf("%d\n",list1[tail1].dep+list2[k].dep); return ; } } } } } len1=strlen(list2[head2].s); for(i=0;i<len1;i++){ for(j=1;j<=n;j++){ if(pan2(list2[head2].s,i,j)){ tail2++; for(k=0;k<i;k++){ list2[tail2].s[k]=list2[head2].s[k]; } int len2=strlen(a[j]); for(l=0;l<len2;l++,k++){ list2[tail2].s[k]=a[j][l]; } len2=strlen(list2[head2].s); for(l=i+strlen(b[j]);l<=len2;l++,k++){ list2[tail2].s[k]=list2[head2].s[l]; } list2[tail2].s[k]='\0'; list2[tail2].dep=list2[head2].dep+1; for (k=1;k<=tail1;k++){ if (check(list1[k].s,list2[tail2].s)) { printf("%d\n",list1[k].dep+list2[tail2].dep); return ; } } } } } head1++; head2++; } printf("NO ANSWER!\n"); } int main(){ scanf("%s%s",list1[1].s,list2[1].s); n=1; while (scanf("%s%s",a[n],b[n])!=EOF) n++; n--; list1[1].dep=list2[1].dep=0; bfs(); return 0; } */ // AC 0MS #include<iostream> using namespace std; struct node{ char s[30]; int dep; } list1[5010],list2[5010]; char a[7][30],b[7][30]; int n; //判断s1、s2字符串是否相等 bool equal(char *s1,char *s2){ while(*s1 && *s2 && *s1==*s2){ s1++; s2++; } if(*s1==0 && *s2==0){ return 1; } return 0; } //判断s2是否为s1的前缀 bool preEqual(char *c1,char *c2){ while(*c2 && *c1==*c2){ c1++; c2++; } if(*c2){ return 0; } return 1; } void bfs(){ int head1,tail1,head2,tail2,i,j,k,l; head1=tail1=head2=tail2=1; while(head1<=tail1 && head2<=tail2){ if(list1[head1].dep+list2[head2].dep>10){ printf("NO ANSWER!\n"); return ; } int len1=strlen(list1[head1].s); for( i=0;i<len1;i++){ for( j=1;j<=n;j++){ if(preEqual(list1[head1].s+i,a[j])){ tail1++; for(k=0;k<i;k++){ list1[tail1].s[k]=list1[head1].s[k]; } int len2=strlen(b[j]); for(l=0;l<len2;l++,k++){ list1[tail1].s[k]=b[j][l]; } len2=strlen(list1[head1].s); for(l=i+strlen(a[j]);l<=len2;l++,k++){ list1[tail1].s[k]=list1[head1].s[l]; } list1[tail1].s[k]=0; list1[tail1].dep=list1[head1].dep+1; for (k=1;k<=tail2;k++){ if (equal(list1[tail1].s,list2[k].s)){ printf("%d\n",list1[tail1].dep+list2[k].dep); return ; } } } } } len1=strlen(list2[head2].s); for(i=0;i<len1;i++){ for(j=1;j<=n;j++){ if(preEqual(list2[head2].s+i,b[j])){ tail2++; for(k=0;k<i;k++){ list2[tail2].s[k]=list2[head2].s[k]; } int len2=strlen(a[j]); for(l=0;l<len2;l++,k++){ list2[tail2].s[k]=a[j][l]; } len2=strlen(list2[head2].s); for(l=i+strlen(b[j]);l<=len2;l++,k++){ list2[tail2].s[k]=list2[head2].s[l]; } list2[tail2].s[k]=0; list2[tail2].dep=list2[head2].dep+1; for (k=1;k<=tail1;k++){ if (equal(list1[k].s,list2[tail2].s)){ printf("%d\n",list1[k].dep+list2[tail2].dep); return ; } } } } } head1++; head2++; } printf("NO ANSWER!\n"); } int main(){ // freopen("test.txt","r",stdin); scanf("%s%s",list1[1].s,list2[1].s); n=1; while (scanf("%s%s",a[n],b[n])!=EOF){ n++; } n--; list1[1].dep=list2[1].dep=0; bfs(); return 0; }