题目传送门
P1032 [NOIP 2002 提高组] 字串变换(疑似错题) - 洛谷
思路
这道题直接BFS暴力搜索即可,但是完全暴力可能会超时(题目数据比较水,所以是可能),所以使用了双向广搜可以降一些时间复杂度。在搜索的时候用unordered_map记录下在不同情况下的字符串的层数,当出现u在另一个unordered_map也出现时就直接返回两者之和ma[u] + mb[u] 。
双向广搜模板
int bfs() {
queue<string> qa, qb;
qa.push(A);
qa.push(B);
while (!qa.empty() && !qb.empty()) {
string u, v;
if (qa.size() < qb.size()) {
extend(qa,.....);
}
else {
extend(qb,.....);
}
}
}AC代码:
#include<bits/stdc++.h>
using namespace std;
unordered_map<string, int> ma;
unordered_map<string, int> mb;
string a, b;
queue<string> qa, qb;
set<pair<string, string>> st;
int bfs() {
qa.push(a), qb.push(b);
while (!qa.empty() && !qb.empty()) {
string u, v;
if (qa.size() < qb.size()) {
u = qa.front();
qa.pop();
if (mb[u] > 0 || u == b) return ma[u] + mb[u];
int idx = -1;
for (auto [x, y] : st) {
idx = u.find(x, idx + 1);
while (idx != -1) {
v = u.substr(0, idx);
v += y;
idx += (int)x.size();
if (idx < (int)u.size()) v += u.substr(idx);
idx = u.find(x, idx);
if (ma[v] > 0) continue;
ma[v] = ma[u] + 1;
qa.push(v);
}
}
}
else {
u = qb.front();
qb.pop();
if (ma[u] > 0 || u == a) return ma[u] + mb[u];
int idx = -1;
for (auto [x, y] : st) {
idx = u.find(y, idx + 1);
while (idx != -1) {
v = u.substr(0, idx);
v += x;
idx += (int)y.size();
if (idx < (int)u.size()) v += u.substr(idx);
idx = u.find(y, idx);
if (mb[v] > 0) continue;
mb[v] = mb[u] + 1;
qb.push(v);
}
}
}
}
return -1;
}
void solve() {
cin >> a >> b;
string x, y;
while (cin >> x >> y) {
st.insert({ x,y });
}
int t = bfs();
if (t == -1) {
cout << "NO ANSWER!" << endl;
}
else {
cout << t << endl;
}
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _ = 1;
//cin >> _;
while (_--) {
solve();
}
return 0;
}P1032 [NOIP 2002 提高组] 字串变换(疑似错题) 题解
http://121.40.154.24:8090/?p=01a02de2-d176-7758-9755-726135e9f96e
评论