【ACWing】190。文字列変換

件名アドレス:

https://www.acwing.com/problem/content/description/192/

2つの既知の文字列AAがありますABBBと一連の文字列変換ルール(最大6 66つのルール):
A1→B1A_1→B_1A1B1
A2→B2A_2→B_2 A2B2
……
ルールの意味は次のとおりです。AAでサブストリングにおけるA 1 A_1をA1B 1B_1に変換できますB1A 2 A_2A2B2…B_2…に変換できますB2...
例:A=abcd B=xyz
変換ルールは次のとおりです。
abc → xu, ud → y, y → yz
この時点で、AAAは一連の変換を通じてBBに変換できますB、変換プロセスは次のとおりです。
"abcd → xud → xy → xyz"
合計3つの変換が実行されるため、AAAはBBに変換されますB

入力形式:
入力形式は次のとおりです
。ABA\ BA B 
A 1 B 1 A_1 \ B_1A1 B1
A 2 B 2 A_2 \ B_2 A2 B2
…………
最初の行は2つの与えられた文字列AAですABBB次の数行、各行は文字列変換規則のセットを説明しています。すべての文字列の最大長は20 202 0

出力フォーマット:
もしで10 10。1 0を含むステップ(10 101 0ステップ)AA内で可能AはBBに変換されますBの場合、最小数の変換ステップを出力します。それ以外の場合は、を出力しますNO ANSWER!

双方向BFSを使用できます。デキューを検討するたびに、最初に少ない要素でキューを拡張できます。コードは次のように表示されます。

#include <iostream>
#include <queue>
#include <unordered_map>
using namespace std;

const int N = 6;

int n;
string a[N], b[N];
int res;

// 返回从q的队头拓展出一步是否会和和另一个方向“会师”
bool extend(queue<string>& q, unordered_map<string, int>& da, unordered_map<string, int>& db, string a[], string b[]) {
    
    
    string t = q.front();
    q.pop();
	
	// 枚举从t的哪个位置开始变换
    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 ne = t.substr(0, i) + b[j] + t.substr(i + a[j].size());
                // 如果之前走到过这个状态,则略过
                if (da.count(ne)) continue;
                // 否则更新一下距离
                da[ne] = da[t] + 1;
				
				// 如果与另一边会师了,则记录一下答案,并返回true
                if (db.count(ne)) {
    
    
                    res = da[ne] + db[ne];
                    return true;
                }

                q.push(ne);
            }

    return false;
}

int bfs(string A, string B) {
    
    
    unordered_map<string, int> da, db;
    da[A] = db[B] = 0;

    queue<string> qa, qb;
    qa.push(A), qb.push(B);

    while (qa.size() && qb.size()) {
    
    
        if (qa.size() <= qb.size()) {
    
    
            if (extend(qa, da, db, a, b)) return res;
        } else if (extend(qb, db, da, b, a)) return res;
    }

    return 11;
}

int main() {
    
    
    string A, B;
    cin >> A >> B;

    while (cin >> a[n] >> b[n]) n++;

    int res = bfs(A, B);
    if (res > 10) cout << "NO ANSWER!" << endl;
    else cout << res << endl;

    return 0;
}

時間計算量O(V + E)O(V + E)O V+E

おすすめ

転載: blog.csdn.net/qq_46105170/article/details/114876760