HDU 4662 MU Puzzle

来源:互联网 发布:淘宝客服介入要多久 编辑:程序博客网 时间:2024/06/11 22:58

比赛

题目

题意:

一个字符串“MI”,每次可以将M后面的所有字符串翻倍,或者将连续的3个I变成一个U,或者消掉2个连续的U,问能否变到目标串。

题解:

可以把U换算成3个I,那么目标串中I的个数有cnt个。而任何地方原来可能有两个U,也就是6个I,设消掉了6x个,那么昨晚翻倍操作后有cnt+6x个I。由于翻倍是每次乘2,所以求是否有x使得6x+cnt为2的幂。

将cnt%6,则cnt-cnt%6可以归入x部分,求出第一个大于cnt-cnt%6的2的幂,则可知要刚好为2的幂还差多少,若不等于cnt%6则翻倍。如果循环则无解。

注意目标串可能有多个M、第一个字符不是M、M后面没有字符等情况,都是No。

//Time://Memory:#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;#define MAXN 1000010#define INF 1000000007char str[MAXN];bool vi[10];int main(){    //freopen("/home/moor/Code/input","r",stdin);    int ncase;    scanf("%d",&ncase);    while(ncase--)    {        scanf("%s",str);        memset(vi,0,sizeof(vi));        int cnt=0;        bool flag=1;        for(int i=1;str[i];++i)            if(str[i]=='I') ++cnt;            else    if(str[i]=='M') flag=0;            else    if(str[i]=='U') cnt+=3;        if(cnt==0)  flag=0;        if(str[0]!='M') flag=0;        if(flag)        {            if(cnt>1)            {                int a=cnt%6,lef=1;                while(lef<cnt-a)                    lef<<=1;                lef%=6;                while(flag)                {                    if(lef==a)    break;                    if(vi[lef]==1)                    {                        flag=0;                        break;                    }                    vi[lef]=1;                    lef=lef*2%6;                }            }        }        printf("%s\n",flag?"Yes":"No");    }    return 0;}


原创粉丝点击