题目描述
已知有两个字串A,BA,B及一组字串变换的规则(至多66个规则):
A1A1 ->B1B1
A2A2 -> B2B2
规则的含义为:在 AA中的子串 A1A1 可以变换为B1B1,A2A2 可以变换为 B2B2 …。
例如:A=abcd
,B=xyz
,
变换规则为:
abc
→xu
,ud
→y
,y
→yz
则此时,AA可以经过一系列的变换变为BB,其变换的过程为:
abcd
→xud
→xy
→xyz
。
共进行了33次变换,使得AA变换为BB。
输入输出格式
输入格式:
输入格式如下:
AA BB
A1A1 B1B1
A2A2 B2B2 |-> 变换规则
... ... /
所有字符串长度的上限为2020。
输出格式:
输出至屏幕。格式如下:
若在1010步(包含1010步)以内能将AA变换为BB,则输出最少的变换步数;否则输出"NO ANSWER!"
输入输出样例
输入样例#1: 复制
abcd xyz abc xu ud y y yz
输出样例#1: 复制
3
#include <bits/stdc++.h>
using namespace std;
typedef struct {
string r1,r2;
}rule;
typedef struct {
string str;
int step;
}node ;
node a{"",0};
string b,t1,t2;
vector<rule>ruler;
map<string, int>mp;
queue<node>sear_que;
void bfs(){
int ans=11;
sear_que.push(a);
while (!sear_que.empty()) {
node s = sear_que.front();
sear_que.pop();
if(s.str==b){ //越早找到的step会越小,不需要取最优
ans=s.step;
break;
}
if(mp[s.str]==1||s.step>=10)continue;
mp[s.str]=1;
for(int i=0;i<s.str.size();i++)
for(int j=0;j<ruler.size();j++){
if(i+ruler[j].r1.size()>s.str.size())continue;
string temp = s.str.substr(i,ruler[j].r1.size());
if(temp==ruler[j].r1){
node t;
t.str=s.str.substr(0,i);
t.str.append(ruler[j].r2);
t.str.append(s.str.substr(i+ruler[j].r1.size()));
t.step=s.step+1;
sear_que.push(t);
}
}
}
if(ans<=10)cout<<ans<<endl;
else cout<<"NO ANSWER!";
}
int main() {
cin>>a.str>>b;
while (cin>>t1>>t2) {
rule r{t1,t2};
ruler.push_back(r);
}
bfs();
return 0;
}