luogu P1032 字串变换
题目描述
已知有两个字串 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
bfs+hash,我比较蠢,不会STL
#include<cstdio> #include<cstring> #include<algorithm> #include<ctime> using namespace std; #define LL long long const int maxn = 100007; int P=31; char s[51],t[51],len[51][2],tf[51][2][51];int cnt=1,len1,len2; int mod=100000007,que[maxn],can[maxn],step[maxn];char tmp[maxn][51],tt[maxn]; bool vis[100000009]; bool bfs() { for(int i=0;i<len1;++i) tmp[0][i]=s[i]; LL h1=0; for(int i=1;i<len1;i++) h1=(h1*P+s[i]+mod)%mod; vis[h1]=1; que[0]=len1; int head=0,tail=1; while(head!=tail) { if(que[head]==len2) { int p=0; for(int i=0;i<len2;++i) if(tmp[head][i]==t[i])p++; else break; if(p==len2) { printf("%d\n",step[head]);return 1; } if(step[head]==10) return 0; } for(int i=0;i<que[head];++i) tt[i]=tmp[head][i]; int lenth=que[head];head++; //printf("%d\n",lenth); for(int i=0;i<lenth;i++) { for(int j=1;j<=cnt;j++) { if(i+len[j][0]>lenth)continue; int p=0; for(int k=0;k<len[j][0];k++) { if(tt[i+k]==tf[j][0][k])p++; else break; } //printf("%d\n",p); if(p==len[j][0]) { //can transfrom for(int k=0;k<i;k++) can[k]=tt[k]; for(int k=0;k<len[j][1];k++)can[i+k]=tf[j][1][k]; for(int k=i+len[j][0];k<lenth;k++) can[k-len[j][0]+len[j][1]]=tt[k]; que[tail]=lenth-len[j][0]+len[j][1]; if(que[tail]>20)continue; LL l=0; for(int k=0;k<que[tail];++k) l=(l*P+can[k]+mod)%mod; if(vis[l])continue; vis[l]=1; for(int k=0;k<que[tail];k++) tmp[tail][k]=can[k]; step[tail]=step[head-1]+1; //printf("%d\n",step[tail]); tail++; } } } } } int main () { scanf("%s%s",s,t); len1=strlen(s); len2=strlen(t); while(scanf("%s%s",tf[cnt][0],tf[cnt][1])!=EOF) { len[cnt][0]=strlen(tf[cnt][0]); len[cnt][1]=strlen(tf[cnt][1]); cnt++; } //printf("%d\n",cnt); if(!bfs()) printf("NO ANSWER!\n"); return 0; }