字串变换
字串变换
这道题用双向广搜会比单向快得多(设每次扩展是 \(k\) 个,则就是 \(k^{10},2k^5\) 二者的差距)。但是还是可以被卡掉的。而且双向广搜还需要注意,每次必须扩展一层。如下图,如果两边同时扩展一个点,那么图中左边的情况有一个中间点,而后面的搜索没有中间点,那么答案就会比最优解大 \(1\),导致错误。
注意
- \(A=B\),特判 \(0\)。
#include<bits/stdc++.h>
using namespace std;
#define Ls(i,l,r) for(int i=l;i<r;++i)
#define Rs(i,l,r) for(int i=r;i>l;--i)
#define L(i,l) for(int i=0;i<l;++i)
const int N=6;
string A,B,a[N],b[N];
int n;
int extend(queue<string>&q,unordered_map<string, int>&da,unordered_map<string, int>db,string a[],string b[]){
int d=da[q.front()];
while(!q.empty()&&da[q.front()]==d){
auto t=q.front();q.pop();
L(i, n)
L(j, t.size())
if(t.substr(j,a[i].size())==a[i]){
string r=t.substr(0,j)+b[i]+t.substr(j+a[i].size());
if(db.count(r))return d+db[r]+1;
if(da.count(r))continue;
da[r]=d+1;
q.emplace(r);
}
}
return 11;
}
int bfs(){
queue<string>qa,qb;
unordered_map<string, int>da,db;
qa.emplace(A);
qb.emplace(B);
da[A]=db[B]=0;
int step=0;
while(!qa.empty()&&!qb.empty()){
int lena=qa.size(),lenb=qb.size(),t;
if(lena<lenb)t=extend(qa, da, db, a, b);
else t=extend(qb, db, da, b, a);
if(t<=10)return t;
if(++step==10)return -1;
}
return -1;
}
int main(){
// freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
// ios::sync_with_stdio(0);
// cin.tie(0);
// cout.tie(0);
cin>>A>>B;
if(A==B)return puts("0"),0;
while(cin>>a[n]>>b[n])n++;
int t=bfs();
if(t==-1)puts("NO ANSWER!");
else printf("%d",t);
return 0;
}