P1032 字串变换
题目描述
已知有两个字串 A,B 及一组字串变换的规则(至多 6个规则):
A1 ->B1
A2 -> B2
规则的含义为:在 A 中的子串 A1 可以变换为 B1 , A2 可以变换为 B2 …。
例如: A =' abcd ' BB =' xyz '
变换规则为:
‘ abc ’->‘ xu ’‘ ud ’->‘ y ’‘ y ’->‘ yz ’
则此时, A 可以经过一系列的变换变为 B ,其变换的过程为:
‘ abcd ’->‘ xud ’->‘ xy ’->‘ xyz ’
共进行了 3 次变换,使得 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 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | #include <iostream> #include<cstdio> #include<algorithm> #include<queue> #include<cstring> #include<string> #include<map> using namespace std; struct node { string s; int step; }; string A,B; string a[10],b[10]; //转换规则 int k; //变换规则数目 map<string,int> mp; // 对已访问过的字符串进行标记,以免重复 string judge(int x,int y,string s) { // x 从哪一个位置开始变换, // y 所用的变换规则 // s 当前字符串 string op=""; int len=s.length(); if(a[y].length()>len-x)return op; // 规则a大于字符串长度,很明显不满足 for(int j=0;j<a[y].length();j++){ if(s[x+j]!=a[y][j])return op; // 不相等,不满足 } op=s.substr(0,x); //前面的部分 op+=b[y]; //转换的部分 op+=s.substr(x+a[y].length()); // 后面的部分 return op; } void bfs() { queue<node> que; node e1,e2; e1.s=A;e1.step=0; que.push(e1); int res=-1; while(que.size()){ e1=que.front();que.pop(); if(mp.count(e1.s)==1) // 已访问 continue; if(e1.s==B){ res=e1.step; break; } mp[e1.s]=1; for(int i=0;i<e1.s.length();i++){ for(int j=0;j<k;j++){ string kl; kl=judge(i,j,e1.s); if(kl!=""){ // 所得字符串不为空,则加入队列 e2.s=kl;e2.step=e1.step+1; que.push(e2); } } } } if(res>10||res==-1)cout <<"NO ANSWER"<<endl; else cout << res << endl; } int main() { cin>>A>>B; k=0; while(cin>>a[k]>>b[k++]); return 0; } |