7.洗牌(简单搜索 BFS)

洗牌

题目链接

题目

给定两叠纸牌 S1S2,每叠恰好有 C 张牌。

每张牌的尺寸大小都完全相同,但是颜色可能不同。

下面介绍洗牌规则。

不妨设 S1 中纸牌从上到下编号依次为 a1,a2,,aCS2 中纸牌从上到下编号依次为 b1,b2,,bC

洗牌就是将这两叠牌交错堆叠在一起,形成一个拥有 2C 张牌的新牌堆 S12

新牌堆中的牌由上至下依次为 a1,b1,a2,b2,,aC,bC

然后,将牌堆从中间一分为二,下半部分是新的 S1,上半部分是新的 S2

这样就可以继续进行洗牌操作获得新的 S12 了。

给定 S1S2 ,请问至少需要进行多少轮洗牌操作方可获得指定牌堆 S12

输入格式

第一行包含一个整数 T ,表示共有 T 组测试数据。

每组数据第一行包含一个整数 C

第二行包含一个长度为 C 的由大写字母构成的字符串,其中第 i 个字母表示初始 S1 中由底向上第 i 张牌的颜色。

第三行包含一个长度为 C 的由大写字母构成的字符串,其中第 i 个字母表示初始 S2 中由底向上第 i 张牌的颜色。

第四行包含一个长度为 2C 的由大写字母构成的字符串,其中第 i 个字母表示目标 S12 中由底向上第 i 张牌的颜色。

输出格式

T 行,每行输出一组数据的结果,首先输出组别编号 i(从1开始),

然后输出所需要的最少洗牌次数。如果无法通过洗牌获得目标牌堆,则输出 −1。

数据范围

1T1000,1C100
卡牌最多有 8 种颜色,用大写字母 AH 表示,所以输入字符串中不会出现其他大写字母。

输入样例:

2
4
AHAH
HAHA
HHAAAAHH
3
CDE
CDE
EEDDCC

输出样例:

1 2
2 -1

思路

按照题意,通过 BFS 搜索情况,,最多枚举 2C 次,就可以知道能否得到该字符串

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;

int n;
int bfs(string a,string b,string c)
{
	queue<string>q;
	map<string,int>d;
	string tem;
	
	for(int i=0;i<n;i++)//第一次洗牌
	{
	    tem+=b[i];
	    tem+=a[i];
	}
	
	q.push(tem);
	d[tem]=1;
	
	
	while(q.size())
	{
		auto t=q.front();
		q.pop();
		
		if(t==c)return d[c];//搜到合法方案
		string tem2;
		
		for(int i=0;i<n;i++)//重新洗牌
		{
		    tem2+=t[i+n];
		    tem2+=t[i];
		}
		
		if(d.count(tem2))return -1;//产生循环,无解
		
		d[tem2]=d[t]+1;
		q.push(tem2);
	}
	
	return -1;
}

int main()
{
	int T;
	cin>>T;
	for(int i=1;i<=T;i++)
	{
		string a,b,c;
		cin>>n>>a>>b>>c;
		printf("%d %d\n",i,bfs(a,b,c));
	}
	
	return 0;
}
posted @   风雨zzm  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示