P1032 字串变换 传送门
不描述题目了.
应该说作为BFS题目还是不难的, 看着就有思路, 题目的数据也是比较小的了.
思路就是: BFS+模拟匹配+去重
注意, 去重是万万不可少的, 不然程序可能会运行很长的时间, 而去重可以大大减少时间.
还要注意不满足条件是NO ANSWER!
, 这里有个感叹号.
#include <algorithm>
#include <iostream>
#include <queue>
#include <set>
#include <vector>
using namespace std;
set<string> see;
string change(string now, pair<string, string> vs, int start)
{
string pattern = vs.first, prod = vs.second;
int i;
for (i = start; i < start + pattern.size(); ++i) {
if (now[i] != pattern[i - start]) return "";
}
string ret;
for (int j = 0; j < start; ++j) {
ret += now[j];
}
ret += prod;
while (i != now.size()) {
ret += now[i];
i++;
}
return ret;
}
int bfs(vector<pair<string, string> > vs, string str1, string str2)
{
queue<pair<string, int> > que;
que.push(make_pair(str1, 0));
while (!que.empty()) {
string now = que.front().first;
int time = que.front().second;
//cout << "now = " << now << " time = " << time << endl;
if (time > 10) return -1;
que.pop();
if (now == str2) return time;
for (int i = 0; i < vs.size(); ++i) {
//cout << "i = " << i << " vs[i].first = " << vs[i].first << endl;
if (now.size() < vs[i].first.size()) continue;
for (int j = 0; j <= now.size() - vs[i].first.size(); ++j) {
/*if (j == 1 && vs[i].first == "ud") {
cout << "匹配结果: " << change(now, vs[i], j) << endl;
}*/
string next = change(now, vs[i], j);
if (see.count(next)) continue;
else see.insert(next);
//cout << "next = " << next << endl;
if (next == "") continue;
que.push(make_pair(next, time + 1));
//break;
//cout << "push le " << next << endl;
}
}
}
return -1;
}
int main()
{
string str1, str2, s1, s2;
cin >> str1 >> str2;
vector<pair<string, string> > vs;
while(cin >> s1 >> s2) {
vs.push_back(make_pair(s1, s2));
}
int ans = bfs(vs, str1, str2);
if (~ans) cout << ans;
else cout << "NO ANSWER!";
}
/*
abaaaba abcdaba
a b
b d
d e
e f
f g
g c // 8
*/
/*
abcd xyz
abc xu
ud y
y yz
*/
/*
BFS模拟遍历过程
找到可匹配的字符串,加入队列当中
不断匹配直到成功或次数达到限制
有一个坑就是一个字符串可能有多个可以匹配的段.
*/