题目描述
已知有两个字串 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!"
输入输出样例
输入样例#1:
abcd xyz
abc xu
ud y
y yz
输出样例#1:
3
出这道题的人真的是丧心病狂,这题没什么思维难度,但是很考代码能力。
我看到有人stl一下就过了,但是我做的可能比较麻烦,广搜加字符串hash。
代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #define ll long long #define il inline #define db double using namespace std; il int gi() { int x=0,y=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') y=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*y; } int len1,len2; int now=1; char begin[45],aim[45]; char chan[45][2][45]; int lon[45][2]; char t[100045][45]; char tmp[45]; char ne[45]; int lenth; int len[100045]; int bu[100045]; int head,tail=1; bool vis[100000045]; int P=31,T=100000007; bool flag=0; il void bfs() { for(int i=0;i<len1;i++) t[0][i]=begin[i]; ll l=0; for(int i=0;i<len1;i++) l=(l*P+begin[i]+T)%T; vis[l]=1; len[0]=len1;//³õʼÈë¶Ó while(head!=tail) { if(len[head]==len2) { int p=0; for(int i=0;i<len2;i++) if(t[head][i]==aim[i]) p++; else break; if(p==len2) { flag=1; printf("%d ",bu[head]); return; } } if(bu[head]==10) { flag=1; printf("NO ANSWER! "); return; } for(int i=0;i<len[head];i++) tmp[i]=t[head][i]; lenth=len[head]; head++;//tmp±£´æ¶ÓÊ× for(int i=0;i<lenth;i++)//Ñ»·Ã¿¸ö×Ö·û¿ªÊ¼ { for(int j=1;j<=now;j++)//ÿ¸ö¿ÉÒÔת»»µÄ¹æÔò { if(i+lon[j][0]>lenth)//cannt change continue; int p=0; for(int k=0;k<lon[j][0];k++)//¿´¿´¿É²»¿ÉÒÔת»» { if(tmp[i+k]==chan[j][0][k]) p++; else break; } if(p==lon[j][0])//be able to change,enter the queue { for(int k=0;k<i;k++) ne[k]=tmp[k]; for(int k=0;k<lon[j][1];k++) ne[i+k]=chan[j][1][k]; for(int k=i+lon[j][0];k<lenth;k++) ne[k-lon[j][0]+lon[j][1]]=tmp[k]; len[tail]=lenth-lon[j][0]+lon[j][1]; if(len[tail]>20) continue; ll l=0; for(int k=0;k<len[tail];k++) l=(l*P+ne[k]+T)%T; if(vis[l]) continue; vis[l]=1; for(int k=0;k<len[tail];k++) t[tail][k]=ne[k]; bu[tail]=bu[head-1]+1; tail++; } } } } } int main() { scanf("%s%s",begin,aim);// ¿ªÊ¼µÄ×Ö·û´®ºÍÄ¿±ê len1=strlen(begin); len2=strlen(aim); while(scanf("%s%s",chan[now][0],chan[now][1])!=EOF)//ÊäÈë¿Éת»»µÄ×Ö·û´® { lon[now][0]=strlen(chan[now][0]); lon[now][1]=strlen(chan[now][1]); now++; } bfs(); if(flag==0) printf("NO ANSWER! "); return 0; }