题目描述 Description
已知有两个字串 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$。
输入描述 Input Description
输入格式如下:
A$ B$
A1$ B1$
A2$ B2$ |-> 变换规则
... ... /
所有字符串长度的上限为 20。
输出描述 Output Description
若在 10 步(包含 10步)以内能将 A$ 变换为 B$ ,则输出最少的变换步数;否则输出"NO ANSWER!"
样例输入 Sample Input
abcd xyz
abc xu
ud y
y yz
样例输出 Sample Output
3
/* 纯搜索,但跑得相当慢,不知道为什么别人都跑得很快 */ #include<cstring> #include<iostream> #include<map> #include<cstdio> using namespace std; string s1,s2,a[11],b[11]; map<string,bool> mp; int n=1,len,flag; bool ok(int l,int r,int k) { string s=""; for(int i=l;i<=r;i++) s+=s1[i]; if(s==a[k])return true; return false; } void init(int l,int r,int k) { string s=""; for(int i=0;i<l;i++)s+=s1[i]; for(int i=0;i<b[k].length();i++)s+=b[k][i]; for(int i=r+1;i<len;i++)s+=s1[i]; s1=s;len=s1.length(); } void dfs(int t,int limit) { if(limit==t) { if(s1==s2)flag=1; return; } for(int i=0;i<len;i++) for(int j=i;j<len;j++) for(int k=1;k<=n;k++) if(ok(i,j,k)) { string zs=s1;int zl=len;init(i,j,k); if(!mp[s1]) { mp[s1]=true; dfs(t+1,limit); s1=zs;len=zl;mp[s1]=false; } else { s1=zs; len=zl; } } } int main() { cin>>s1>>s2;len=s1.length(); while(cin>>a[n]>>b[n])++n; if(s1==s2) { printf("0"); return 0; } string zs=s1;int zl=len; for(int i=1;i<=10;i++) { mp.clear(); s1=zs;len=zl; dfs(0,i); if(flag) { printf("%d",i); return 0; } } printf("NO ANSWER!"); return 0; }