洗牌
题目描述
分析
首先经过多次洗牌, 最终一定会复原, 也就是说整个过程是一个闭环(好吧,我不会证明Orz)
看一下其他大佬的证明
图片来源
我写的时候自然是证明不出是 2c 一个循环, 那就让它给自己比吧,什么时候跟最初一样,就说明转完一圈了, 如果此时还没有成为指定牌堆, 那就一定无法再变成目标牌堆!!!
AC 代码
#include <iostream>
#include <cstring>
using namespace std;
string s1, s2, s, ss, str;
int n, t, cnt;
bool flag;
int main()
{
cin >> t;
for(int i = 1; i <= t; i ++)
{
cin >> n;
cin >> s1 >> s2 >> s;
// 记录最初的状态
str = s1 + s2;
int cnt = 0;
// 是否经历了一个循环
while(str != ss)
{
cnt ++;
flag = false;
ss = ""; // 合并两副牌
for(int i = 0; i < n; i ++)
{
ss += s2[i];
ss += s1[i];
}
s1 = "", s2 = ""; // 拆开两幅牌
for(int i = 0; i < n; i ++) s1 += ss[i];
for(int i = n; i < 2*n; i ++) s2 += ss[i];
// 判断是否达到要求
if(ss == s)
{
flag = true;
cout << i << ' ' << cnt << endl;
break;
}
}
if(!flag) cout << i << ' ' << -1 << endl;
}
return 0;
}