D - Shuffle'm Up
在扑克桌上,扑克玩家常常会玩一种叫做“洗筹码”的游戏。洗筹码是通过将两堆扑克筹码 S1 和 S2 进行交错堆叠来完成的,每堆筹码包含 C 个筹码。每堆筹码可能包含多种不同颜色的筹码。
实际的洗牌操作是通过将 S1 中的一枚筹码与 S2 中的一枚筹码交错堆叠来完成的,如下所示,当 C = 5 时:
得到的单一结果堆 S12 包含 2 * C 个筹码。 S12 的底部筹码是来自 S2 的底部筹码。在这枚筹码上面,是来自 S1 的底部筹码。交错堆叠过程继续,将来自 S2 底部第二枚筹码放在 S12 上,然后是来自 S1 底部第二枚筹码,以此类推,直到将来自 S1 的顶部筹码放在 S12 上。
洗牌操作后,S12 被分成两堆新的筹码,从 S12 底部取出 C 枚筹码形成新的 S1,从 S12 顶部取出 C 枚筹码形成新的 S2。然后可以重复洗牌操作形成新的 S12。
对于这个问题,你需要编写一个程序来确定特定的结果堆 S12 是否可以通过多次洗牌操作形成。
输入
输入的第一行包含一个整数 N,(1 ≤ N ≤ 1000),表示接下来的数据集的数量。
每个数据集包括四行输入。数据集的第一行指定一个整数 C,(1 ≤ C ≤ 100),表示每堆初始筹码(S1 和 S2)中的筹码数量。每个数据集的第二行指定 S1 中每个 C 枚筹码的颜色,从底部筹码开始。每个数据集的第三行指定 S2 中每个 C 枚筹码的颜色,从底部筹码开始。颜色用单个大写字母表示(A 到 H)。筹码颜色之间没有空格或分隔符。每个数据集的第四行包含 2 * C 个大写字母(A 到 H),表示 S1 和 S2 洗牌零次或多次后所期望的结果颜色。底部筹码的颜色首先被指定。
输出
每个数据集的输出包括一行,显示数据集编号(从 1 到 N),一个空格,以及一个整数值,表示获得期望结果堆所需的最小洗牌次数。如果使用数据集中的输入无法获得期望结果,则显示值 -1 作为洗牌次数。
样例
Inputcopy | Outputcopy |
---|---|
2 4 AHAH HAHA HHAAAAHH 3 CDE CDE EEDDCC | 1 2 2 -1 |
思路:利用一个map容器,根据题目意思讲s1,s2使用循环依次将筹码堆叠,每堆叠一次将次数+1,再对其将得到的字符串与题目需要的字符串进行对比,若相同即打印行数和次数然后跳出,若map容器中该字符串出现次数没有变化即打印”-1“后跳出,每次进行下一次循环前要将其分成s1和s2两部分.
代码:
#include <iostream>
#include<stdio.h>
#include <algorithm>
#include <queue>
#include<map>
#include <cstring>
using namespace std;
char s1[300], s2[300], ss[500],s[500];
int n, ans, len;
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> len;
cin >> s1 >> s2 >> s;
map<string, int>q;
q[s] = 1;
ans = 0;
while (1)
{
int t = 0;
for (int j = 0; j <= len; j++)
{
ss[t++] = s2[j];
ss[t++] = s1[j];
}
ans++;
if (strcmp(ss, s) == 0)
{
printf("%d %d\n", i, ans);
break;
}
if (q[ss] == 1)
{
printf("%d -1\n", i);
break;
}
q[ss] = 1;
for (int k = 0; k < len; k++)
{
s1[k] = ss[k];
s2[k] = ss[k + len];
}
}
}
return 0;
}