欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > AcWing 190. 字串变换 --BFS-双向搜索

AcWing 190. 字串变换 --BFS-双向搜索

2025/2/23 1:28:50 来源:https://blog.csdn.net/weixin_57011178/article/details/145622391  浏览:    关键词:AcWing 190. 字串变换 --BFS-双向搜索

 

已知有两个字串 A, B 及一组字串变换的规则(至多 66 个规则):

A1→B1

A2→B2

规则的含义为:在 A 中的子串 A1A1 可以变换为 B1、A2 可以变换为 B2…。

例如:A=abcd B=xyz

变换规则为:

abc →→ xu ud →→ y y →→ yz

则此时,AA 可以经过一系列的变换变为 BB,其变换的过程为:

abcd →→ xud →→ xy →→ xyz

共进行了三次变换,使得 AA 变换为 BB。

注意,一次变换只能变换一个子串,例如 AA=aa BB=bb

变换规则为:

a →→ b

此时,不能将两个 a 在一步中全部转换为 b,而应当分两步完成。

输入格式

输入格式如下:

A B
A1 B1
A2 B2
… …

第一行是两个给定的字符串A 和 B。

接下来若干行,每行描述一组字串变换的规则。

所有字符串长度的上限为 20。

输出格式

若在 10 步(包含 10 步)以内能将 A 变换为 B ,则输出最少的变换步数;否则输出 NO ANSWER!

输入样例:
abcd xyz
abc xu
ud y
y yz
输出样例:
3
// 包含必要的头文件
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <unordered_map>// 使用标准命名空间
using namespace std;// 定义常量N,表示最多处理的字符串对数
const int N = 6;// n表示实际输入的字符串对数,A和B为初始和目标字符串
int n;
string A, B;
// a数组和b数组分别存储输入的字符串对
string a[N], b[N];/*** extend函数用于从当前队列中扩展新的字符串,尝试从a变换到b* @param q 队列,存储待处理的字符串* @param da 存储从起始字符串到当前字符串的变换次数* @param db 存储从目标字符串到当前字符串的变换次数* @param a 字符串对中的起始字符串数组* @param b 字符串对中的目标字符串数组* @return 如果找到解,则返回变换次数,否则返回11*/
int extend(queue<string>& q, unordered_map<string, int>&da, unordered_map<string, int>& db, string a[N], string b[N])
{// d表示当前处理的字符串的变换次数int d = da[q.front()];// 遍历队列中所有变换次数为d的字符串while (q.size() && da[q.front()] == d){auto t = q.front();q.pop();// 尝试将字符串t中的a[i]替换为b[i]for (int i = 0; i < n; i ++ )for (int j = 0; j < t.size(); j ++ )if (t.substr(j, a[i].size()) == a[i]){// r表示替换后的字符串string r = t.substr(0, j) + b[i] + t.substr(j + a[i].size());// 如果在反向搜索中已经处理过r,则表示找到了解if (db.count(r)) return da[t] + db[r] + 1;// 如果当前方向已经处理过r,则跳过if (da.count(r)) continue;// 更新r的变换次数,并将其加入队列da[r] = da[t] + 1;q.push(r);}}// 如果没有找到解,则返回11return 11;
}/*** bfs函数使用双向BFS搜索,尝试找到从A变换到B的最少次数* @return 如果找到解,则返回变换次数,否则返回-1*/
int bfs()
{// 如果A和B相同,则不需要变换,返回0if (A == B) return 0;// 定义两个队列,分别用于正向和反向搜索queue<string> qa, qb;// 定义两个哈希表,分别存储正向和反向搜索的字符串变换次数unordered_map<string, int> da, db;// 初始化队列和哈希表qa.push(A), qb.push(B);da[A] = db[B] = 0;// step表示当前的变换次数int step = 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;// 如果变换次数超过10,则表示无法找到解,返回-1if ( ++ step == 10) return -1;}// 如果没有找到解,则返回-1return -1;
}/*** main函数为程序的入口点* @return 程序的退出状态*/
int main()
{// 输入初始和目标字符串cin >> A >> B;// 输入字符串对,直到输入结束while (cin >> a[n] >> b[n]) n ++ ;// 使用bfs函数寻找解int t = bfs();// 如果没有找到解,则输出"NO ANSWER!"if (t == -1) puts("NO ANSWER!");// 否则输出变换次数else cout << t << endl;// 程序正常退出return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词