洛谷 P1032 字串变换

这篇博客探讨了如何利用广度优先搜索(BFS)解决一个字符串变换问题,其中给定了两个字符串A和B以及一系列变换规则。博主通过代码展示了解决方案,旨在找出使A转换成B所需的最少变换步骤。如果在10步内可以完成转换,输出最小步数,否则输出"NO ANSWER!"。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

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

A_1A1​ ->B_1B1​

A_2A2​ -> B_2B2​

规则的含义为:在 AA中的子串 A_1A1​ 可以变换为B_1B1​,A_2A2​ 可以变换为 B_2B2​ …。

例如:AA='abcdabcd'BB='xyzxyz'

变换规则为:

‘abcabc’->‘xuxu’‘udud’->‘yy’‘yy’->‘yzyz’

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

‘abcdabcd’->‘xudxud’->‘xyxy’->‘xyzxyz’

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

 

输入格式:

AA BB
A_1A1​ B_1B1​
A_2A2​ B_2B2​ |-> 变换规则

... ... /

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

 

输出格式:

若在1010步(包含1010步)以内能将AA变换为BB,则输出最少的变换步数;否则输出"NO ANSWER!"

输入输出样例

输入样例#1:

abcd xyz
abc xu
ud y
y yz

输出样例#1:

3

思路:

直接用广度优先搜索(BFS)来做,加上用set来判重,具体看代码

 

代码

#include <iostream>
#include <set>
#include <queue>
#include <cstring>
using namespace std;
string a,b,s[10],e[10]; 
int x=1,p=1;//x:记录变化规则数量  p:特判 
struct node{
	string a;//字符串 
	int sum;//已经变化次数 
};
queue<node> que;
set<string> mark;//用来判重,否则会TLE在第3点和第5点
void bfs()//重点
{
	if(a==b)
	{
		cout<<"0"<<endl;
		return;
	}
	node t={a,0};
	que.push(t);
	mark.insert(a);
	while(!que.empty())
	{
		node front=que.front();
		que.pop();
		if(front.sum>20)
		{
			cout<<"NO ANSWER!"<<endl;
			p=0;
			return;
		}
		for(int i=1;i<=x;i++)
		{	
			int v=0;
			//找出所有符合字符串入队 
			while(1)							
			{
				//找出符合条件的位置 
				v=front.a.find(s[i],v);
				//判断是否找到符合的条件 string::npos==-1 
				if(v!=string::npos)
				{
					//合并新串 
					string newstr=front.a.substr(0,v)+e[i]+front.a.substr(v+strlen(s[i].c_str()));
					//根据题目字符串最长20 
					if(strlen(newstr.c_str())>20){v++;continue;}
					//相等直接输出结果 
					if(newstr==b)
					{
						cout<<front.sum+1<<endl;
						p=0;
						return;
					}
					//判重,重复的串不再入队 
					if(mark.find(newstr)==mark.end())
					{
						mark.insert(newstr);
						node newnode={newstr,front.sum+1};
						que.push(newnode);
					}
					//从下一个位置开始找 
					v++;
				}
				else
				{
					break;
				}
			}
		}
	}
	//还有一种情况:变化次数少于20且没有正确答案
	if(p)cout<<"NO ANSWER!"<<endl;
	return;
}
int main()
{
	cin>>a>>b;
	while(cin>>s[x]>>e[x])x++;
	bfs();
	return 0;
}

  

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值