洛谷-P1032 字串变换
题目描述
已知有两个字串 A,B 及一组字串变换的规则(至多 6 个规则):
(A_1) ->$ B_1$
(A_2) -> (B_2)
规则的含义为:在 A 中的子串 (A_1) 可以变换为 $ B_1(,)A_2$ 可以变换为 (B_2) …。
例如:(A= ext{abcd}),(B= ext{xyz}),
变换规则为:
( ext{abc} ightarrow ext{xu}),( ext{ud} ightarrow ext{y}),( ext{y} ightarrow ext{yz})
则此时,A 可以经过一系列的变换变为 B,其变换的过程为:
( ext{abcd} ightarrow ext{xud} ightarrow ext{xy} ightarrow ext{xyz})。
共进行了 3 次变换,使得 A 变换为 B。
输入格式
输入格式如下:
A B
(A_1) (B_1)
(A_2) (B_2) |-> 变换规则
... .../
所有字符串长度的上限为 20。
输出格式
若在 10 步(包含 10 步)以内能将 A 变换为 B,则输出最少的变换步数;否则输出 NO ANSWER!
输入输出样例
输入 #1
abcd xyz
abc xu
ud y
y yz
输出 #1
3
C++代码
#include <iostream>
#include <cstring>
#include <queue>
#include <map>
using namespace std;
int n;
string a,b,orginal[6],translated[6];
struct node{
string str;
int step;
}ans;
queue<node> q;
map<string,int> m;
node bfs(string a) {
int i,pos;
node s,t;
s.str=a;
s.step=0;
q.push(s);
while(!q.empty()) {
s=q.front(),q.pop();
if(s.str==b||s.step>10)
break;
if(m[s.str]==1)
continue;
for(i=0,pos=-1;i<n-1;++i) {
while((pos=s.str.find(orginal[i],pos+1))!=string::npos) {
t=s;
t.str.replace(pos,orginal[i].length(),translated[i]);
t.step=s.step+1;
q.push(t);
}
}
m[s.str]=1;
}
return s;
}
int main() {
cin>>a>>b;
while(cin>>orginal[n]>>translated[n++]);
ans=bfs(a);
if(ans.step<=10&&ans.str==b)
cout<<ans.step<<endl;
else
cout<<"NO ANSWER!"<<endl;
return 0;
}