题目描述
已知有两个字串 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
1 /* 2 双向bfs 3 同时搜索 不需要剪枝 4 巧妙利用string函数 5 */ 6 #include<map> 7 #include<queue> 8 #include<string> 9 #include<cstdio> 10 #include<iostream> 11 #define MAXN 10 12 13 using namespace std; 14 15 string str[MAXN],str2[MAXN]; 16 17 string pre,last; 18 19 int n=1; 20 21 bool f[MAXN]; 22 23 queue<string> head,tail; 24 25 map<string,int> visa,visb; 26 27 inline void bfs() { 28 visa[pre]=1;visb[last]=1; 29 head.push(pre); 30 tail.push(last); 31 while(1) { 32 if(head.empty()||tail.empty()) {cout<<"NO ANSWER!"<<endl;return;} 33 string ta,tb; 34 ta=head.front(); 35 tb=tail.front(); 36 for(int i=1;i<=n;i++) { 37 int k=0; 38 while(ta.find(str[i],k)!=-1) {//以下函数不懂得可以自己百度 39 k=ta.find(str[i],k); 40 int len=str[i].size(); 41 ta.replace(k,len,str2[i]); 42 if(visa[ta]==0) { 43 visa[ta]=visa[head.front()]+1; 44 head.push(ta); 45 } 46 if(visb[ta]!=0) { 47 printf("%d ",visa[ta]+visb[ta]-2); 48 return; 49 } 50 k++; 51 ta=head.front(); 52 } 53 k=0; 54 while(tb.find(str2[i],k)!=-1) { 55 k=tb.find(str2[i],k); 56 int len=str2[i].size(); 57 tb.replace(k,len,str[i]); 58 if(visb[tb]==0) { 59 visb[tb]=visb[tail.front()]+1; 60 tail.push(tb); 61 } 62 if(visa[tb]!=0) { 63 printf("%d ",visa[tb]+visb[tb]-2); 64 return; 65 } 66 k++; 67 tb=tail.front(); 68 } 69 } 70 head.pop(); 71 tail.pop(); 72 } 73 return; 74 } 75 76 int main() { 77 cin>>pre>>last; 78 while(cin>>str[n]>>str2[n]){n++;} 79 n--; 80 bfs(); 81 return 0; 82 }