题目描述
已知有两个字串A,BA,B及一组字串变换的规则(至多66个规则):
A_1A1 ->B_1B1
A_2A2 -> B_2B2
规则的含义为:在 AA中的子串 A_1A1 可以变换为B_1B1,A_2A2 可以变换为 B_2B2 …。
例如:AA='abcdabcd'BB='xyzxyz'
变换规则为:
‘abcabc’->‘xuxu’‘udud’->‘yy’‘yy’->‘yzyz’
则此时,AA可以经过一系列的变换变为BB,其变换的过程为:
‘abcdabcd’->‘xudxud’->‘xyxy’->‘xyzxyz’
共进行了33次变换,使得AA变换为BB。
输入输出格式
输入格式:
输入格式如下:
AA BB
A_1A1 B_1B1
A_2A2 B_2B2 |-> 变换规则
... ... /
所有字符串长度的上限为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;
int n,ans;
map<string,int> vis;
string a,b,x[25],y[25];
struct node
{
string str;
int step;
};
string convert(string &s,int pos,int k)//按运算规则转换母串
{
string temp = "";
if (s.length()<pos+x[k].length()) return temp;
for (int i=0;i<x[k].length();i++)
if (s[pos+i]!=x[k][i])
return temp;
temp = s.substr(0,pos); //sbustr(pos)取从pos开始的子串
temp += y[k];
temp += s.substr(pos+x[k].length());
return temp;
}
void bfs()
{
node s;
s.str = a;
s.step = 0;
queue<node> q;
q.push(s);
while (!q.empty())
{
node now;
now = q.front();
q.pop();
string temp;
if (vis.count(now.str)==1) continue;
if (now.str==b)
{
ans = now.step;
break;
}
vis[now.str] = 1;
for (int i=0;i<now.str.length();i++)//逐个字符搜索
for (int j=0;j<n;j++)//逐个转换方式搜索
{
temp = convert(now.str,i,j);
if (temp!="")
{
node next;
next.str = temp;
next.step = now.step + 1;
q.push(next);
}
}
}
if (0<ans && ans<=10) cout<<ans<<endl;
else cout<<"NO ANSWER!"<<endl;
}
int main()
{
//freopen("in.txt","r",stdin);
n = 0;
cin>>a>>b;//不知道多少组数据 只剩ctrl+z结束输入
while(cin>>x[n]>>y[n]) n++;
bfs();
return 0;
}