#include <stdio.h>
#include <iostream>
#include <string.h>
#define N 1000010
using namespace std;
int n, s[N*3];
char a[N];
void love()
{
memset(s, 0, sizeof(s));
for(int i = 1; i < N*3; i <<= 1)
{
s[i] = 1;
for(int j = 6; i-j >= 0; j += 6)
s[i-j] = 1;
}
}
int solve()
{
int q = 0;
for(int i = 1; a[i]; ++i)
{
if(a[i] == 'M')
return 0;
else if(a[i] == 'I')
q++;
else
q += 3;
}
return s[q];
}
int main()
{
love();
scanf("%d", &n);
while(n--)
{
scanf("%s", a);
if(a[0] != 'M')
puts("No");
else
puts(solve() ? "Yes" : "No");
}
return 0;
}
下午做的时候看到题就想到了规律问题。
这种规律变换的题一般都有自己所变化的顺序。
因为第一个变换说的是双击M后面的字符,所以对于一个字符串数组a[N]来说,从a[0]往后如果单纯 从这个角度来说就是2^i个元素。
所以只要第一个元素M后面有2^i个'I'元素就是可变换的。
然后第二个变换是3个‘I’换成一个‘U’,第三个变换就是2个'U'可以去掉。这样周期就是6.所以在love函数里面就会遭到规律了。
对于每一个2^i的元素都是可以用2^i个‘I’元素表示。
对于2^i-6*j的元素是'U'和'I'来表示的。
那么对于一个全部是0的数组,每当下标附和这些元素的下标,就赋值为1。
每一个‘I’代表1个元素,每一个‘u’代表3个元素,所输入的字符串每一个都扫一遍,计算出元素个数,如果在s【】数组中值为1,那么就可以变换,否则不可。
至此1A。