AcWing 190. 字串变换

原题连接:AcWing 190. 字串变换

题意:

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

A1B1
A2B2

规则的含义为:在 A 中的子串 A1 可以变换为 B1A2 可以变换为 B2

例如:AabcdBxyz

变换规则为:

abcxuudyyyz

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

abcdxudxyxyz

共进行了三次变换,使得 A 变换为 B

输入格式

输入格式如下:

AB
A1B1
A2B2
… …

第一行是两个给定的字符串 AB

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

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

输出格式

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

双向BFS:

从起始状态,目标状态分别开始,两边轮流进行,每次扩展数量小的那一层(即队列中元素数小的那一层),扩展一层,当两边各自一个状态在记录数组中发生重复时,就说明两个搜索过程相遇了,可以合并得到起点的最小步数。

// Problem: 字串变换
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/192/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>

using namespace std;

const int N = 6;

int n;
string a[N], b[N];

int extend(queue<string> &q, unordered_map<string, int> &da, unordered_map<string, int> &db, string a[], string b[]) {
	int SZ = q.size();
	while (SZ--) {
		auto t = q.front();
		q.pop();
		
		for (int i = 0; i < t.size(); i++) { //枚举字符串起点
			for (int j = 0; j < n; j++) { 
				if (t.substr(i, a[j].size()) == a[j]) {
					string state = t.substr(0, i) + b[j] + t.substr(i + a[j].size());
					if (da.count(state)) continue;
					if (db.count(state)) return da[t] + 1 + db[state];
					da[state] = da[t] + 1;
					q.push(state);
				}
			}
		}
	}
	
	return 11;
}

int bfs(string A, string B) {
	unordered_map<string, int> da, db;
	queue<string> qa, qb;
	qa.push(A);
	qb.push(B);
	da[A] = 0, db[B] = 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;
	}
	
	return 11;
}

int main() {
    string A, B;
	cin >> A >> B;
	while (cin >> a[n] >> b[n]) n++;
	
	int step = bfs(A, B);
	if (step > 10) puts("NO ANSWER!");
	else cout << step << endl;
	
    return 0;
}
posted @   Xxaj5  阅读(53)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示