NOIP 2002 提高组 洛谷P1032"字串变换"的BFS解法与优化策略
一、问题描述
给定初始字符串A和目标字符串B,以及若干变换规则(将特定子串替换为另一子串)。要求通过不超过10步变换,将A转换为B,求最少变换步数。若无法在10步内完成,输出"NO ANSWER!"。
二、解题思路
三、C++代码实现
#include <iostream> #include <queue> #include <unordered_map> #include <string> using namespace std; struct Rule { string from; string to; }; struct State { string str; int step; }; int main() { string A, B; cin >> A >> B; vector<Rule> rules; string from, to; while (cin >> from >> to) { rules.push_back({from, to}); } queue<State> q; unordered_map<string, bool> visited; q.push({A, 0}); visited[A] = true; while (!q.empty()) { State current = q.front(); q.pop(); if (current.str == B) { cout << current.step << endl; return 0; } if (current.step >= 10) continue; // 尝试所有可能的变换规则 for (const auto& rule : rules) { size_t pos = current.str.find(rule.from); while (pos != string::npos) { string newStr = current.str; newStr.replace(pos, rule.from.length(), rule.to); if (!visited[newStr]) { visited[newStr] = true; q.push({newStr, current.step + 1}); } pos = current.str.find(rule.from, pos + 1); } } } cout << "NO ANSWER!" << endl; return 0; }
四、算法详解
五、关键点解析
字符串查找替换:注意处理所有出现位置
去重处理:避免重复状态无限循环
步数限制:题目要求的10步限制
边界条件:初始状态即为目标状态
六、复杂度分析
时间复杂度:O(n^m),n为规则数,m为步数限制
空间复杂度:O(k),k为状态数
七、学习建议
原创内容 转载请注明出处