传送门
题意
给定字符串(A、B),给定串(A)的变换规则,问能否通过10次变换内将(A)变成(B)
数据范围
(1leq |A|、|B|leq 20)
题解
两个队列分别是从起始向终点搜和反向搜索
- 每次都从当前层数少的进行扩展,实际运行下较优
- (substr(int ;i,int; j))函数表示的是从(i)开始长度为(j)的子串
- (unordered\_map)记录距离以及是否搜索到
Code
#include<bits/stdc++.h>
using namespace std;
#define ump unordered_map
string a[7],b[7];
int n;
int extend(queue<string>&q,ump<string,int>&dst,ump<string,int>&ded,string a[],string b[]){
// 每次扩展当前一层节点
for(int k=0,lk=q.size();k<lk;k++){
string t=q.front();
q.pop();
for(int i=0;i<t.size();i++)
for(int j=0;j<n;j++){
if(t.substr(i,a[j].size()) == a[j]){
string now=t.substr(0,i)+b[j]+t.substr(i+a[j].size()); // substr 只有起点时为起点到终点
if(dst.count(now)) continue; // 已经入队
if(ded.count(now)) return dst[t]+ded[now]+1;
dst[now]=dst[t]+1;
q.push(now);
}
}
}
return 11;
}
int bfs(string A,string B){
queue<string>qst,qed;
ump<string,int>dst,ded;
qst.push(A);qed.push(B);
dst[A]=0;ded[B]=0;
while(qst.size() && qed.size()){
int t;
if(qst.size()<=qed.size()) t=extend(qst,dst,ded,a,b);
else t=extend(qed,ded,dst,b,a);
if(t<=10) return t;
}
return 11;
}
int main(){
string A,B;
cin>>A>>B;
while(cin>>a[n]>>b[n]) n++;
int step=bfs(A,B);
if(step > 10) cout<<"NO ANSWER!"<<endl;
else cout<<step<<endl;
return 0;
}