题目描述:
已知有两个字串 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!"
样例输入:
abcd xyz abc xu ud y y yz
样例输出:
3
我们可以利用广搜(BFS)来解决该问题,
以下是代码:
#include<bits/stdc++.h>
using namespace std;
int n;
string s_begin,s_end,s1,s2,s3,a[1010],b[1010];
struct data{
string s;
int step;
};
queue<data> q;
map<string,bool> vis;
int main(){
cin>>s_begin>>s_end;
while(cin>>s1>>s2){
a[++n]=s1;
b[n]=s2;
}
q.push(data{s_begin,0});
vis[s_begin]=1;
while(!q.empty()){
s1=q.front().s;
int step=q.front().step;
if(step==11){
break;
}
if(s1==s_end){
cout<<step;
exit(0);
}
q.pop();
for(int i=1;i<=n;i++){
for(int j=0;j<=int(s1.length()-a[i].length());j++){
s3=s1;
s2=s1.substr(j,a[i].length());
if(s2==a[i]){
s1.replace(j,a[i].length(),b[i]);
if(vis[s1]==0){
vis[s1]=1;
q.push(data{s1,step+1});
}
}
s1=s3;
}
}
}
cout<<"NO ANSWER!";
return 0;
}
当然,也可以用BFS函数来写,道理是一样的:
#include<bits/stdc++.h>
using namespace std;
int n;
string s_begin,s_end,s1,s2,s3,a[1010],b[1010];
struct data{
string s;
int step;
};
queue<data> q;
map<string,bool> vis;
int BFS(){
q.push(data{s_begin,0});
vis[s_begin]=1;
while(!q.empty()){
s1=q.front().s;
int step=q.front().step;
if(step==11){
break;
}
if(s1==s_end){
return step;
exit(0);
}
q.pop();
for(int i=1;i<=n;i++){
for(int j=0;j<=int(s1.length()-a[i].length());j++){
s3=s1;
s2=s1.substr(j,a[i].length());
if(s2==a[i]){
s1.replace(j,a[i].length(),b[i]);
if(vis[s1]==0){
vis[s1]=1;
q.push(data{s1,step+1});
}
}
s1=s3;
}
}
}
}
int main(){
cin>>s_begin>>s_end;
while(cin>>s1>>s2){
a[++n]=s1;
b[n]=s2;
}
BFS();
cout<<"NO ANSWER!";
return 0;
}
如有疑问,可以在下方评论中提出哦~
小编会尽量解决你的问题。