本题疑似错题,不保证存在靠谱的多项式复杂度的做法。测试数据非常的水,各种做法都可以通过,不代表算法正确。因此本题题目和数据仅供参考。
已知有两个字串 A , B A,B A,B 及一组字串变换的规则(至多 6 6 6 个规则),形如:
规则的含义为:在 A A A 中的子串 A 1 A_1 A1 可以变换为 $ B_1 , , ,A_2$ 可以变换为 B 2 ⋯ B_2\cdots B2⋯。
例如: A = abcd A=\texttt{abcd} A=abcd, B = xyz B=\texttt{xyz} B=xyz,
变换规则为:
则此时, A A A 可以经过一系列的变换变为 B B B,其变换的过程为:
共进行了 3 3 3 次变换,使得 A A A 变换为 B B B。
第一行有两个字符串 A , B A,B A,B。
接下来若干行,每行有两个字符串 A i , B i A_i,B_i Ai,Bi,表示一条变换规则。
若在
10
10
10 步(包含
10
10
10 步)以内能将
A
A
A 变换为
B
B
B,则输出最少的变换步数;否则输出 NO ANSWER!
。
abcd xyz
abc xu
ud y
y yz
3
对于 100 % 100\% 100% 数据,保证所有字符串长度的上限为 20 20 20。
【题目来源】
NOIP 2002 提高组第二题
#include
using namespace std;
struct node {
string str;
int step;
node(string ss, int ste) {
str = ss, step = ste;
}
};
string a, b;
pair<string, string> s[10];
int cnt, ans = 1000000;
queue<node> q;
void bfs() {
while (!q.empty()) {
node now = q.front();
q.pop();
if (now.step > 10)
continue;
if (now.str == b) {
ans = now.step;
}
for (int i = 0; i < cnt; i++) {
//子串可能存在多个,分别替换每一个
int idx = -1;
while (1) {
string ss = now.str;//不能直接对now.str进行replace等修改
//从上一个子串的下一位置idx + 1寻找,避免一直找的是第一个
idx = ss.find(s[i].first, idx + 1);
if (idx == -1)
break;
ss.replace(idx, s[i].first.size(), s[i].second);
if (ss == b) {
ans = now.step + 1;
return;
}
q.push(node(ss, now.step + 1));
}
}
}
}
int main() {
cin >> a >> b;
while (cin >> s[cnt].first && cin >> s[cnt++].second);
q.push(node(a, 0));
bfs();
if (ans != 1000000)
cout << ans;
else
cout << "NO ANSWER!";
return 0;
}
#include
using namespace std;
string a, b;
pair<string, string> s[10];
int cnt, ans = 1000000;
void dfs(string str, int step) {
if (step > ans || step > 10)
return;
if (str == b) {
ans = min(ans, step);
return;
}
for (int i = 0; i < cnt; i++) {
//子串可能存在多个,分别替换每一个,分别dfs
int idx = -1;
while (1) {
string ss = str;
//从上一个子串的下一位置寻找,避免一直找的是第一个
idx = ss.find(s[i].first, idx + 1);
if (idx == -1)
break;
ss.replace(idx, s[i].first.size(), s[i].second);
dfs(ss, step + 1);
}
}
}
int main() {
cin >> a >> b;
while (cin >> s[cnt].first && cin >> s[cnt++].second);
dfs(a, 0);
if (ans != 1000000)
cout << ans;
else
cout << "NO ANSWER!";
return 0;
}