描述
题解
哎,第二次打 CF 就被第二题卡死了,不是难不难的问题,是真心英语差,忽略了(因为没看懂)一个极其重要的条件,结果想难了。
题目大意是给定一个串,串无论怎么分割,相邻的四个字母均不相同,当然,也只有这四个字母,!
表示未知,我们需要知道这些感叹号都是什么字母,但是不需要知道准确的字母位置,只要知道这四个字母分别需要多少个才能把’!’替换完。
一开始将第二行最后一句理解错了,以为是每四盏灯至少有一个亮,于是我还怀疑起来样例有问题,后来直接忽视了这句话,毕竟我没有看懂。然后呢,我开始用一种极其笨重的做法,不断匹配字母,填补字母,考虑到了很多没有意义的东西。
然后,忽然感觉到,这个问题不是暴力匹配替换的问题,而应该是找规律的问题,于是乎,重新审视了第二段最后一句,理解到大意是每个字母至少出现一次……于是这就用到一个规律直接可以解出来,如果要保证每四个相邻的字母不同,那么第i
个字母绝对和第i-4
、i+4
个字母相同,如果存在的话。所以,同样是暴力解,只用暴力替换就行了,不用过多考虑匹配问题,之前就是考虑了很多匹配的问题,而忽略了规律。
当然,不得不说,我最开始出问题不光光是因为没有理解题意,而是自己没有静下心来观察问题的一般性规律,当知道规律时,根本用不到考虑匹配问题,直接暴力替换即可。
哎,我还是太渣了,一道简单的问题一时思路闭塞,没有找对方向,就一直坑下去了,还没有及时醒悟~/(ㄒoㄒ)/~~
代码
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 111;
char S[MAXN];
int kr, kb, ky, kg;
void init()
{
kr = kb = ky = kg = 0;
}
int main(int argc, const char * argv[])
{
while (cin >> S)
{
init();
int len = (int)strlen(S);
while (true)
{
int flag = 0;
for (int i = 0; i < len; i++)
{
if (S[i] == '!')
{
flag = 1;
if (i > 3 && S[i - 4] != '!')
{
S[i] = S[i - 4];
switch (S[i - 4])
{
case 'R':
kr++;
break;
case 'B':
kb++;
break;
case 'Y':
ky++;
break;
case 'G':
kg++;
break;
}
}
else if (i < len - 4 && S[i + 4] != '!')
{
S[i] = S[i + 4];
switch (S[i + 4])
{
case 'R':
kr++;
break;
case 'B':
kb++;
break;
case 'Y':
ky++;
break;
case 'G':
kg++;
break;
}
}
}
}
if (!flag)
{
break;
}
}
printf("%d %d %d %d\n", kr, kb, ky, kg);
}
return 0;
}