题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4662
题目:
Suppose there are the symbols M, I, and U which can be combined to produce strings of symbols called "words". We start with one word MI, and transform it to get a new word. In each step, we can use one of the following transformation rules:
1. Double any string after the M (that is, change Mx, to Mxx). For example: MIU to MIUIU.
2. Replace any III with a U. For example: MUIIIU to MUUU.
3. Remove any UU. For example: MUUU to MU.
Using these three rules is it possible to change MI into a given string in a finite number of steps?
Input
First line, number of strings, n.
Following n lines, each line contains a nonempty string which consists only of letters 'M', 'I' and 'U'.
Total length of all strings <= 10 6.
Output
n lines, each line is 'Yes' or 'No'.
Sample Input
2 MI MU
Sample Output
Yes No
思路:
因为一个U等于三个I,所以可以把U都统计到I上,然后由于M后的字母可以扩大两倍,所以MI可以有的I是1,2,4,8……都是2的幂。而两个U可以消除,也就是说6个I可以消除,那么只要用比I大的2的幂-I去模6等于0就可以变成MI。
代码:
#include <cstdio>
#include <cstring>
#include<iostream>
using namespace std;
const int maxn = 1000010;
char s[maxn];
int p[30];
void init()
{
p[0] = 1;
for(int i = 1; i < 30; i++)
p[i] = (p[i-1] << 1);
}
bool solve()
{
bool ok = 0;
int len = strlen(s), i, M = 0, I = 0;
for(i = 0; i < len; i++)
{
if(s[i] == 'M') M++;
else if(s[i] == 'I') I++;
else if(s[i] == 'U') I += 3;
}
if(M == 1 && s[0] == 'M')
{
for(i = 29; i >= 0; i--)
if(p[i] >= I && (p[i] - I) % 6 == 0) { ok = 1; break; }
}
return ok;
}
int main()
{ int n;
init();
cin>>n;
getchar();
while(n--)
{
scanf("%s", s);
if(solve()) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}