2555. 解谜游戏
题目链接
2555. 解谜游戏
小明正在玩一款解谜游戏。
谜题由 \(24\) 根塑料棒组成,其中黄色塑料棒 \(4\) 根,红色 \(8\) 根,绿色 \(12\) 根 (后面用 \(Y\) 表示黄色、\(R\) 表示红色、\(G\) 表示绿色)。
初始时这些塑料棒排成三圈,如上图所示,外圈 \(12\) 根,中圈 \(8\) 根,内圈 \(4\) 根。
小明可以进行三种操作:
将三圈塑料棒都顺时针旋转一个单位。例如当前外圈从 \(0\) 点位置开始顺时针依次是 YRYGRYGRGGGG
,中圈是 RGRGGRRY
,内圈是 GGGR
。那么顺时针旋转一次之后,外圈、中圈、内圈依次变为:GYRYGRYGRGGG
、YRGRGGRR
和 RGGG
。
将三圈塑料棒都逆时针旋转一个单位。例如当前外圈从 \(0\) 点位置开始顺时针依次是 YRYGRYGRGGGG
,中圈是 RGRGGRRY
,内圈是 GGGR
。那么逆时针旋转一次之后,外圈、中圈、内圈依次变为:RYGRYGRGGGGY
、GRGGRRYR
和 GGRG
。
将三圈 \(0\) 点位置的塑料棒做一个轮换。具体来说:外圈 \(0\) 点塑料棒移动到内圈 \(0\) 点,内圈 \(0\) 点移动到中圈 \(0\) 点,中圈 \(0\) 点移动到外圈 \(0\) 点。例如当前外圈从 \(0\) 点位置开始顺时针依次是 YRYGRYGRGGGG
,中圈是 RGRGGRRY
,内圈是 GGGR
。那么轮换一次之后,外圈、中圈、内圈依次变为:RRYGRYGRGGGG
、GGRGGRRY
和 YGGR
。
小明的目标是把所有绿色移动到外圈、所有红色移动中圈、所有黄色移动到内圈。
给定初始状态,请你判断小明是否可以达成目标?
输入格式
第一行包含一个整数 \(T\),代表询问的组数。
每组询问包含 \(3\) 行:
第一行包含 \(12\) 个大写字母,代表外圈从 \(0\) 点位置开始顺时针每个塑料棒的颜色。
第二行包含 \(8\) 个大写字母,代表中圈从 \(0\) 点位置开始顺时针每个塑料棒的颜色。
第三行包含 \(4\) 个大写字母,代表内圈从 \(0\) 点位置开始顺时针每个塑料棒的颜色。
输出格式
对于每组询问,输出一行 YES
或者 NO
,代表小明是否可以达成目标。
数据范围
\(1≤T≤100\)
输入样例:
2
GYGGGGGGGGGG
RGRRRRRR
YRYY
YGGGRRRRGGGY
YGGGRRRR
YGGG
输出样例:
YES
NO
解题思路
规律
为内、中和外圈分别编号为 \(0\sim 3、0\sim 7、0\sim 11\),则可以发现:可以整体上分为如下 \(4\) 快,且每一块之间互不影响:
0 0 0
0 4 4
0 0 8
------
1 1 1
1 5 5
1 1 9
------
2 2 2
2 6 6
2 2 10
------
3 3 3
3 7 7
3 3 11
现在目标是使每一块外圈有 \(3\) 个 \(G\),中圈有 \(2\) 个 \(R\),内圈有 \(1\) 个 \(Y\),因为每一块对应的影响的外、中和内圈的位置分别有 \(3、2、1\) 个
又由三圈之间的轮换关系,以第一块为例,可将三圈中的对应位置换成如下 \(9\) 种位置:
\(\color{red}{只要开始时的位置上的 G、R、Y 的个数分别为 3、2、1 就能满足条件?}\)
一个比较粗略的想法是:考虑外圈,外圈包含了所有的位置,可以先将 \(3\) 个 \(G\) 全部移到外圈,然后在不影响外圈的基础上进一步操作,此时可以选择的操作有:
此时把仅剩的 \(1\) 个 \(Y\) 移到内圈即可
- 时间复杂度:\(O(T)\)
代码
// %%%Skyqwq
#include <bits/stdc++.h>
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
template <typename T> void inline read(T &x) {
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}
template <typename T>
void print(T x) {
if (x < 0) putchar('-'), x = -x;
if (x < 10) putchar(x + 48);
else print(x / 10), putchar(x % 10 + 48);
}
template <typename T>
void print(T x, char t) {
print(x); putchar(t);
}
int t;
char s[3][105];
int main()
{
for(cin>>t;t;t--)
{
cin>>s[0]>>s[1]>>s[2];
bool f=true;
for(int i=0;i<4;i++)
{
unordered_map<char,int> mp;
for(int k=0;k<3;k++)
for(int j=i;s[k][j];j+=4)mp[s[k][j]]++;
if(!(mp['Y']==1&&mp['R']==2&&mp['G']==3))
{
f=false;
break;
}
}
puts(f?"YES":"NO");
}
return 0;
}