题目描述
已知有两个字串 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。
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
\
|-> 变换规则
... ... /
所有字符串长度的上限为 20。
输出描述:
输出格式如下:
若在10步(包含 10步)以内能将A变换为B,则输出最少的变换步数;否则输出"NO ANSWER!"
示例1
输入
abcd xyz
abc xu
ud y
y yz
输出
3
解答
1.读完题目,样例模拟成功,但感觉该题挺难的,无从下手。
2.搜索网络后,才明白,因为有多种变换规则,故一次变换有多种可能,故采用广度优先遍历方法。
3.数据输入量:至多6个规则 所有字符串长度的上限为 20
4.感觉该题比较简单,编码,提交60分,测试点4,5 均RE。
5.将队列q[1000]改成q[10000],测试点4通过,测试点5还是RE,再改大数组还是无功而返。单向搜索,80分到头。
6.采用双向搜索,参考他人代码,收获很大,但提交还是80分,无奈只好对拍,才发现字符串变换出了问题,必须整个字符串搜索完毕,按规则逐个变换才能算一步变换结束,之前的问题是,字符串只变化第一次找到的字符,没有第二次第三次查找,算法存在较大问题。
7.问题找到后,开始修改,工程量不小。
8.核心代码:p=strstr(b+d+strlen(left[i]),left[i]);//查找剩下的字符串,该题最难之处
9.修改,提交AC。
2.搜索网络后,才明白,因为有多种变换规则,故一次变换有多种可能,故采用广度优先遍历方法。
3.数据输入量:至多6个规则 所有字符串长度的上限为 20
4.感觉该题比较简单,编码,提交60分,测试点4,5 均RE。
5.将队列q[1000]改成q[10000],测试点4通过,测试点5还是RE,再改大数组还是无功而返。单向搜索,80分到头。
6.采用双向搜索,参考他人代码,收获很大,但提交还是80分,无奈只好对拍,才发现字符串变换出了问题,必须整个字符串搜索完毕,按规则逐个变换才能算一步变换结束,之前的问题是,字符串只变化第一次找到的字符,没有第二次第三次查找,算法存在较大问题。
7.问题找到后,开始修改,工程量不小。
8.核心代码:p=strstr(b+d+strlen(left[i]),left[i]);//查找剩下的字符串,该题最难之处
9.修改,提交AC。
#include <stdio.h> #include <string.h> char input[100],output[100]; int lena=0; struct node{ char in[30];//in[100] int s;//步数 }q1[1000],q2[1000];//q[1000] char left[10][30],right[10][30];//变换规则 void bfs(char *input,char *output){ int h1,t1,i,j,d,h2,t2; char b[30],*p;//b[100] h1=t1=0; strcpy(q1[t1].in,input); q1[t1].s=0; t1++; h2=t2=0; strcpy(q2[t2].in,output); q2[t2].s=0; t2++; if(strcmp(q1[t1-1].in,q2[t2-1].in)==0){ printf("%d\n",q1[t1-1].s+q2[t2-1].s); return; } while(h1<t1&&h2<t2){ if(q1[h1].s+q2[h2].s>10) break; strcpy(b,q1[h1].in); for(i=0;i<lena;i++){//变换处理 p=strstr(b,left[i]); while(p!=NULL){ d=p-b; strncpy(q1[t1].in,b,d); strcat(q1[t1].in,right[i]); strcat(q1[t1].in,&b[d+strlen(left[i])]); q1[t1].s=q1[h1].s+1; for(j=0;j<t2;j++) if(strcmp(q1[t1].in,q2[j].in)==0){ printf("%d\n",q1[t1].s+q2[j].s); return; } t1++; p=strstr(b+d+strlen(left[i]),left[i]);//查找剩下的字符串,该题最难之处 } } h1++; strcpy(b,q2[h2].in); for(i=0;i<lena;i++){//变换处理 p=strstr(b,right[i]); while(p!=NULL){//原来是if,现改成while d=p-b; strncpy(q2[t2].in,b,d); strcat(q2[t2].in,left[i]); strcat(q2[t2].in,&b[d+strlen(right[i])]); q2[t2].s=q2[h2].s+1; for(j=0;j<t1;j++) if(strcmp(q2[t2].in,q1[j].in)==0){ printf("%d\n",q1[j].s+q2[t2].s); return; } t2++; p=strstr(b+d+strlen(right[i]),right[i]);//用了比较长的时间才理解。 } } h2++; } printf("NO ANSWER!\n"); } int main(){ int i,j; char a[30],b[30]; scanf("%s%s",input,output);//读取变换前后字符串 while(scanf("%s%s",a,b)==2){//读取变换规则 strcpy(left[lena],a); strcpy(right[lena],b); lena++; } bfs(input,output); return 0; }
来源:mrcrack