字串变换 双向广搜

双向广搜

同时从起点状态和终点状态开始广搜,从而提高搜索效率

190. 字串变换

已知有两个字串 AA, BB 及一组字串变换的规则(至多 66 个规则):

A1→B1A1→B1

A2→B2A2→B2

规则的含义为:在 AA 中的子串 A1A1 可以变换为 B1B1、A2A2 可以变换为 B2…B2…。

例如:AA=abcd BB=xyz

变换规则为:

abc` →→ `xu` `ud` →→ `y` `y` →→ `yz

则此时,AA 可以经过一系列的变换变为 BB,其变换的过程为:

abcd` →→ `xud` →→ `xy` →→ `xyz

共进行了三次变换,使得 AA 变换为 BB。

输入格式

输入格式如下:

AA BB
A1A1 B1B1
A2A2 B2B2
… …

第一行是两个给定的字符串 AA 和 BB。

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

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

输出格式

若在 1010 步(包含 1010 步)以内能将 AA 变换为 BB ,则输出最少的变换步数;否则输出 NO ANSWER!

输入样例

abcd xyz
abc xu
ud y
y yz

输出样例

3

思路:

从始末两个状态同时扩展,相遇时返回结果即可

代码:

#include<iostream>
#include<vector>
#include<cstdio>
#include<cmath>
#include<unordered_map>
#include<cstring>
#include<queue>

using namespace std;

#define x first
#define y second
typedef pair<int, int> PII;
const int N = 6;
int m, n;
int res;
string a[N], b[N];

// 记得&!!!
int extend(queue<string> &q, unordered_map<string, int> &da, unordered_map<string, int> &db, string a[], string b[]) {
    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 state = t.substr(0, i) + b[j] + t.substr(i + a[j].size());
                // 如果另一个方向扩展过这个状态便直接返回步数和
                if (db.count(state)) return da[t] + 1 + db[state];
                // 如果当前方向扩展过这个状态便进行下一次扩展
                if (da.count(state)) continue;
                // 否则存下当前状态及步数
                da[state] = da[t] + 1;
                q.push(state);
            }
        }
    }
    // 找不到就返回任意一个大于10的数字
    return 100;
}

int bfs(string A, string B) {
    if (A == B) return 0;
    queue<string> qa, qb;
    unordered_map<string, int> da, db;
    qa.push(A);
    da[A] = 0;
    qb.push(B);
    db[B] = 0;
    int t = 0;
    while (qa.size() && qb.size()) {
        // 优先扩展状态少的队列
        if (qa.size() <= qb.size()) t = extend(qa, da, db, a, b);
        else t = extend(qb, db, da, b, a);
        if (t <= 10) return t;
    }
    return 100;
}


int main() {
    string A, B;
    cin >> A >> B;
    while (cin >> a[n] >> b[n]) n++;
    int step = bfs(A, B);
    if (step > 10) puts("NO ANSWER!");
    else cout << step << endl;
    return 0;
}
posted @   嘿,抬头!  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示