给定两叠纸牌 S1 和 S2,每叠恰好有 C 张牌。
每张牌的尺寸大小都完全相同,但是颜色可能不同。
下面介绍洗牌规则。
不妨设 S1 中纸牌从上到下编号依次为 a1,a2,…,aC 中纸牌从上到下编号依次为 b1,b2,…,bC。
洗牌就是将这两叠牌交错堆叠在一起,形成一个拥有 2C 张牌的新牌堆 S12。
新牌堆中的牌由上至下依次为 a1,b1,a2,b2,…,aC,bC。
可参考下图:
然后,将牌堆从中间一分为二,下半部分是新的 S1,上半部分是新的 S2。
这样就可以继续进行洗牌操作获得新的 S12 了。
给定 S1 和 S2,请问至少需要进行多少轮洗牌操作方可获得指定牌堆 S12。
输入格式
第一行包含一个整数 T,表示共有 T 组测试数据。
每组数据第一行包含一个整数 C。
第二行包含一个长度为 C 的由大写字母构成的字符串,其中第 i 个字母表示初始 S1 中由底向上第 i张牌的颜色。
第三行包含一个长度为 C的由大写字母构成的字符串,其中第 i 个字母表示初始 S2 中由底向上第 i 张牌的颜色。
第四行包含一个长度为 2C2 的由大写字母构成的字符串,其中第 i 个字母表示目标 S12 中由底向上第 i 张牌的颜色。
输出格式
共 T 行,每行输出一组数据的结果,首先输出组别编号 i(从 1 开始),然后输出所需要的最少洗牌次数。如果无法通过洗牌获得目标牌堆,则输出 −1。
数据范围
1≤T≤1000,
1≤C≤100。
卡牌最多有 88 种颜色,用大写字母 A∼H 表示,所以输入字符串中不会出现其他大写字母。输入样例:
2 4 AHAH HAHA HHAAAAHH 3 CDE CDE EEDDCC
输出样例:
1 2 2 -1
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <cmath> #include <queue> #include <set> #include <map> #include <stack> using namespace std; //#define int long long typedef pair<int,int>PII; constexpr int N=10000; int n; map<string,int>m; string solve(string q1,string q2){ string res; for(int i=0;i<n;i++) res+=q2[i],res+=q1[i]; return res; } int bfs(string s1,string s2,string s3){ int ans=0; while(true){ ans++; string q= solve(s1,s2); if(q==s3){ return ans; } else{ if(m[q]==1){ return -1; } else{ m[q]++; s2=q.substr(n,n); s1=q.substr(0,n); } } } } signed main() { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t; cin>>t; int k=0; while(t--){ string s1,s2,s3; m.clear(); cin>>n; cin>>s1>>s2>>s3; cout<<++k<<" "<<bfs(s1,s2,s3)<<endl; } return 0; }
4221 洗牌
最新推荐文章于 2024-10-01 04:50:10 发布