当前位置: 首页 > news >正文

双向bfs-字串变换

题面

已知有两个字串 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
… …

第一行是两个给定的字符串 A 和 B。

接下来若干行,每行描述一组字串变换的规则。

所有字符串长度的上限为 20。

输出格式
若在 10 步(包含 10 步)以内能将 A 变换为 B ,则输出最少的变换步数;否则输出 NO ANSWER!。

输入样例:

abcd xyz
abc xu
ud y
y yz

输出样例:

3

思路:
因为本题的变换步骤可能会很多,6^10次变换,有可能会超时,所以要使用双向bfs,即同时从起点和终点开始搜索,只要搜到相同的状态就算完成。实现代码如下:

#include <iostream>
#include <string>
#include <unordered_map>
#include <queue>
using namespace std;
const int N = 8;
string a[N],b[N];
string A,B;
int n;
int extend(queue<string> &q,unordered_map<string,int> &dist_a,unordered_map<string,int> &dist_b,string a[N],string b[N]){
    string t = q.front();
    int d = dist_a[t];
    while(!q.empty()&&dist_a[q.front()]==d){
        auto temp = q.front();
        q.pop();
        for(int i = 0;i<temp.size();i++){
            for(int j = 0;j<n;j++){
                if(temp.substr(i,a[j].size())==a[j]){
                    string r = temp.substr(0,i)+b[j]+temp.substr(i+a[j].size());
                    if(dist_b.count(r)) return dist_a[t]+dist_b[r]+1;
                    if(dist_a.count(r)) continue;
                    dist_a[r] = dist_a[t]+1;
                    q.push(r);
                }
            }

        }
    }


}

int bfs(){
    if(A==B) return 0;
    queue<string> qa,qb;
    unordered_map<string,int> dist_a,dist_b;
    qa.push(A);
    qb.push(B);
    dist_a[A] = 0;
    dist_b[B] = 0;
    int step = 0;
    while(!qa.empty()&&!qb.empty()){
        int x;
        if(qa.size()>=qb.size()){
            x = extend(qb,dist_b,dist_a,b,a);
        }else{
            x = extend(qa,dist_a,dist_b,a,b);
        }
        if(x<=10) return x;
        if(++step==10) return -1;
    }
    return -1;
}
int main() {

    cin>>A>>B;
    while(cin>>a[n]>>b[n]) n++;
    int step = bfs();
    if(step==-1){
        cout<<"NO ANSWER!"<<endl;
    }
    else cout<<step<<endl;

    return 0;
}

相关文章:

  • 的品质网站建设/超级seo工具
  • 天津做网站公司哪家好/上海单个关键词优化
  • 飞机查询网站开发的创新点/无经验能做sem专员
  • 网站换域名要怎么做/百度seo在哪里
  • 十大奢侈品排名/一个企业seo网站的优化流程
  • 成都网站建设著名公司/chrome官网下载
  • 软考报名有没有学历要求?2023年软考报名条件分享
  • linux下调节GPU的功率限制
  • 冥想第六百七十五天
  • 牛客竞赛每日俩题 - 动态规划4
  • python 列表生成式
  • MongoDB面试题整理-四年经验
  • 机器学习笔记之深度玻尔兹曼机(一)玻尔兹曼机系列整体介绍
  • 【Linux】探索缓冲区的概念 | Git 三板斧 | 实现简易进度条
  • JS语言基础
  • 详解分布式系统核心概念——CAP、CP和AP
  • 【JavaEE初阶】第二节.进程篇
  • dockerfile笔记