洛谷P1032 字串变换

题目描述

已知有两个字串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

基本上是爆搜,剪不剪枝好像都无所谓,因为题目也没给具体输入多少数据,所以目前只能用txt来存储测试样例进行输入了

有一个坑,如果一个主串包含不止一个子串,例如:abcAabcAabc这样就包含了三个子串,我们这时候就要分别对其replace

巧妙灵活运用replace,find函数很关键啊

code:

#include<bits/stdc++.h> 
using namespace std;
struct node{string s;int t;};
string sa,sb,s1[7],s2[7];
map<string,bool> V;
int li=0,flag=0;
queue<node> Q;
node temp;
void bread()//广搜 
{
	Q.push((node){.s=sa,.t=0});
	while(!Q.empty())
	{
		temp=Q.front();	Q.pop();
	
		if(temp.s==sb)//符合条件 
		{
			cout<<temp.t;
			flag=1;
			return ;	
		}
		if(temp.t>10)	return ;
		
		for(int i=0;i<li;i++)//爆搜 
		{
			int id=temp.s.find(s1[i],0);
			while(id!=-1)//可能一个主串包含多个子串 
			{
				string ts=temp.s;
				ts.replace(id,s1[i].length(),s2[i]);
				if(V[ts]==0)//如果这个字符串没有出现过 
				Q.push((node){.s=ts,temp.t+1}), V[ts]=1;
				id=temp.s.find(s1[i],id+1);//往后查找 
			}
		}
	}
}
int main()
{
	//freopen("in.txt","r",stdin);
	cin>>sa>>sb;
	while(cin>>s1[li]>>s2[li]) li++;
	bread();
	if(flag==0) cout<<"NO ANSWER!";
	return 0;
}



 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值