题目描述
已知有两个字串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’->‘yy’->‘yz’
则此时,A可以经过一系列的变换变为B,其变换的过程为:
‘abcd’->‘xud’->‘xy’->‘xyz’
共进行了3次变换,使得A变换为B。
输入输出格式
输入格式:
输入格式如下:
AA BB
A_1A1 B_1B1
A_2A2 B_2B2 |-> 变换规则
... ... /
所有字符串长度的上限为20。
输出格式:
输出至屏幕。格式如下:
若在10步(包含10步)以内能将A变换为B,则输出最少的变换步数;否则输出"NO ANSWER!"
输入输出样例
输入样例#1
abcd xyz abc xu ud y y yz
输出样例#1
3
思路
广度优先搜索,每次字符串入队列后找可以执行的操作(即看一下有没有可以修改的串),把修改之后的字符串入队列,记录修改的次数。
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
string str1,str2,ca[21],cb[21];
typedef struct
{
string now;//当前串
int moved;//修改次数
}lxydl;
lxydl que[2000001];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
register int i(1),j,head(0),tail(1);
cin>>str1>>str2;
while(cin>>ca[i]>>cb[i])
{
i++;
}
i--;
que[tail].now=str1;
que[tail].moved=0;
while(head<tail)
{
head++;
if(que[head].moved>10)
{
cout<<"NO ANSWER!"<<endl;
return 0;
}
else for(j=1;j<=i;j++)
{
int x=que[head].now.find(ca[j],0);
while(1)//寻找可以修改的子串
{
if(x==-1)//如果找不到
{
break;
}
else//找到了塞进队列
{
tail++;
que[tail].now=que[head].now;
que[tail].moved=que[head].moved+1;
que[tail].now.replace(x,ca[j].size(),cb[j]);
if(que[tail].now==str2)
{
cout<<que[tail].moved;
return 0;
}
else
{
x=que[head].now.find(ca[j],x+1);
}
}
}
}
}
return 0;
}