洛谷 P1032 字串变换

题目描述

已知有两个字串A,BA,BA,B及一组字串变换的规则(至多666个规则):
A1A_1A1​ ->B1 B_1B1​
A2A_2A2​ -> B2B_2B2​
规则的含义为:在 AAA中的子串 A1A_1A1​ 可以变换为B1 B_1B1​,A2A_2A2​ 可以变换为 B2B_2B2​ …。
例如:A=abcd,B=xyz,
变换规则为:
abc→xu,ud→y,y→yz
则此时,AAA可以经过一系列的变换变为BBB,其变换的过程为:
abcd→xud→xy→xyz。
共进行了333次变换,使得AAA变换为BBB。

输入格式

输入格式如下:
AAA BBB
A1A_1A1​ B1B_1B1​
A2A_2A2​ B2B_2B2​ |-> 变换规则
… … /
所有字符串长度的上限为202020。

输出格式

输出至屏幕。格式如下:
若在101010步(包含101010步)以内能将AAA变换为BBB,则输出最少的变换步数;否则输出"NO ANSWER!"

输入输出样例

输入

abcd xyz
abc xu
ud y
y yz

输出

3

AC代码

#include<iostream>
#include<string>
#include<queue>
#include<map>
using namespace std;
string str_st,str_en;  //串 A B
string A[7], B[7];     //可转化形式
queue<string> que;     //存放待匹配字符串
queue<int> step;	   //与que队列对应 对应字符串所对应的匹配
map<string, int> mp;    //剪枝用 (字符串是否已经被匹配过)
int n;
int bfs() {
	bool bo = false;                                //得到最终串后退出循环的条件
	while (que.empty() == 0&&step.front()<10)      //队列不为空且步数小于10
	{
		if (mp[que.front()] == 1)                  //当前串被搜索过  出队
		{
			step.pop();
			que.pop();
			continue;
		}
		mp[que.front()] = 1;                       //标记被搜索的字符串
		for (int i = 0; i < n; i++)                //遍历转换方式
		{
			string str = que.front();              
			while (true)                           //循环到当前串中无当前需转换串
			{
				int place = str.find(A[i]);        //得到子串的位置
				if (place == -1)				  //没有子串 退出循环
				   	break;
				//获得转化后的新字符串 并将其入队
				string str_1 = que.front();        
				str_1.replace(place, A[i].size(), B[i]);
				que.push(str_1);
				//消除第一次出现的子串(将母串中的当前发现子串的第一个字母换成特殊符号)
				str[place] = '*';
				//新串步数入栈
				step.push(step.front() + 1);
				//是否退出循环
				if (str_1 == str_en)
				{
					bo = true;
					break;
				}
			}
			//是否退出循环
			if (bo)
				break;
		}
		//出队操作
		que.pop();
		step.pop();
		//返回步数队尾元素  即最小步数
		if (bo)
			return step.back();
	}
	return 0;
}
int main() {
	cin >> str_st >> str_en; 
	//第一个串及步数入队
	que.push(str_st);
	step.push(0);

	while (cin >> A[n] >> B[n]) n++;
	int ans = bfs();
	if (ans != 0)
		cout << ans << endl;
	else
		cout << "NO ANSWER!" << endl;
	return 0;
}

本题除了掌握广度优先搜索 还要了解string数据类型的常用操作

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值