字串变换

字串变换

这道题用双向广搜会比单向快得多(设每次扩展是 \(k\) 个,则就是 \(k^{10},2k^5\) 二者的差距)。但是还是可以被卡掉的。而且双向广搜还需要注意,每次必须扩展一层。如下图,如果两边同时扩展一个点,那么图中左边的情况有一个中间点,而后面的搜索没有中间点,那么答案就会比最优解大 \(1\),导致错误。

注意

  • \(A=B\),特判 \(0\)

image-20230520084915666

#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;
}
posted @ 2023-05-20 09:17  wscqwq  阅读(5)  评论(0编辑  收藏  举报