Typesetting math: 100%

【双向广搜】 字串变换

传送门

题意

给定字符串AB,给定串A的变换规则,问能否通过10次变换内将A变成B

数据范围

1|A||B|20

题解

两个队列分别是从起始向终点搜和反向搜索

  • 每次都从当前层数少的进行扩展,实际运行下较优
  • substr(inti,intj)函数表示的是从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;
}

本文作者:Hyx'

本文链接:https://www.cnblogs.com/hhyx/p/13918335.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Hyx'  阅读(67)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起