已知有两个字串 AA
, BB
及一组字串变换的规则(至多6个规则):A1A1
-> B1B1
A2A2
-> B2B2
…规则的含义为:在 AA
中的子串 A1A1
可以变换为 B1B1
、A2A2
可以变换为 B2B2
…。例如:AA
=’abcd’ BB
=’xyz’变换规则为:‘abc’->‘xu’ ‘ud’->‘y’ ‘y’->‘yz’则此时,AA
可以经过一系列的变换变为 BB
,其变换的过程为:‘abcd’->‘xud’->‘xy’->‘xyz’共进行了三次变换,使得 AA
变换为BB
。输入格式输入格式如下:AA
BB
A1A1
B1B1
A2A2
B2B2
|-> 变换规则
… … /所有字符串长度的上限为 20。 输出格式若在 10 步(包含 10步)以内能将 AA
变换为 BB
,则输出最少的变换步数;否则输出”NO ANSWER!”输入样例:abcd xyz
abc xu
ud y
y yz
输出样例:3
思路:从起点和终点同时搜索,哪头短便搜索哪头
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <unordered_map>
using namespace std;
const int N = 6;
int n;
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);
}
return 11;
}
int bfs(string A,string B){
queue <string> qa,qb;
unordered_map <string, int> da,db;
qa.push(A), da[A] = 0;
qb.push(B), db[B] = 0;
while(qa.size() && qb.size()){
int t;
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 11;
}
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 printf("%d\n", step);
return 0;
}