题目描述
已知有两个字串 A, B 及一组字串变换的规则(至多6个规则):
A1 -> B1
A2 -> B2
规则的含义为:在 A$中的子串 A1 可以变换为 B1、A2 可以变换为 B2 …。
例如:A=’abcd’B=’xyz’
变换规则为:
‘abc’->‘xu’‘ud’->‘y’‘y’->‘yz’
则此时,A 可以经过一系列的变换变为 B,其变换的过程为:
‘abcd’->‘xud’->‘xy’->‘xyz’
共进行了三次变换,使得 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
这道题明显看出就是bfs,唯一困难的一点就是在字符串的处理上……如何按照规则替换原有字符变成新的字符串并放到队列中,当然这些如果知道string的replace函数的话就不是问题……
replace(替换第i个字符开始,替换长度,替换旧字符串的新字符串)
顺便标记字符串是否用过可以用map
以下代码orz
#include <iostream>
#include <queue>
#include <map>
#include <string>
using namespace std;
//abcd xyz
//abc xu
//ud y
//y yz
string r[110],q[110];
map <string,int> flag;
struct st{
string str;
int step;
st(string a,int b):str(a),step(b){}
};
int main()
{
queue <st> qe;
string a,b;
cin>>a>>b;
int i=0,j,k;
while(cin>>r[i]>>q[i]) i++;
int n=i;
qe.push(st(a,0));
while(!qe.empty()){
st t=qe.front();
qe.pop();
if(t.step>10){
cout<<"NO ANSWER!"<<endl;
return 0;
}
if(b==t.str){
cout<<t.step<<endl;
return 0;
}
for(i=0;i<n;i++){
for(j=0;j<t.str.length();j++){
if(t.str[j]==r[i][0]){
int g=j;
int p=j;
bool flag1=1;
for(k=1,p=j+1;k<r[i].length()&&p<t.str.length();k++,p++){
if(t.str[p]!=r[i][k]){
flag1=0;
break;
}
}
if(flag1){
string h=t.str;
h.replace(g,r[i].length(),q[i]);
if(!flag[h]){
qe.push(st(h,t.step+1));
// cout<<h<<endl;
flag[h]=1;
}
}
}
}
}
}
cout<<"NO ANSWER!"<<endl;
return 0;
}