【HDOJ】4662 MU Puzzle

【题目】http://acm.hdu.edu.cn/showproblem.php?pid=4662

【报告】

    按照题目意思,第一条,可以把M后面的复制一份,第二条,可以把3个I换成一个U,第三条,可以把2个U删掉。把I算成1,,那么一个字符串可以对应一个数字S(但一个S不一定对应一个字符串)。第一条,显然,就是S*=2;第二条,一个U就可以算成3个I,也就是3;第三条,一次删去两个U,相当于S-=6。

    题目问的是有限步骤是否可以达成。我们把初始状态当成1,把结束字符串转换为一个数字。相当于是否可以通过这3种变换方式(其实只有2种),把1变成目标数字S。通过数学计算,相当于求 s=2^x1-6x2是否有正整数解(x1,x2为未知数)因为数据范围原因,可以直接暴力求解。

    还有一些注意的,就是输入。首先,单独一个M应该是算No的,一个串里面出现2个M也是不行的,第一个字符不是M也是不行的。(被坑惨了。。)

    这不是标程给的算法,苏牛说我这个算法能A完全是因为数据比较弱。不是很理解的说。。。

【程序】

// Task: 4662 MU Puzzle
// Designer: Rsky 2013/08/10
#include
#include
#include
#include
using namespace std;
#define L 1000000
char st[L+1];
int main()
{
    int t;
    scanf("%d",&t);
    while (t--)
    {
        scanf("%s",st);
        if (strlen(st)<=1||st[0]!='M')
        {
            printf("No\n");
            continue;
        }
        int s=0;
        bool flag=true;
        for (int i=strlen(st)-1;i>=1;i--)
            if (st[i]=='I') s++;
            else if (st[i]=='U') s+=3;
            else flag=false;
        if (!flag)
        {
            printf("No\n");
            continue;
        }
     //   cout << "s=" << s << endl;
        int k1,k2;
        bool ans=false;
        for (k1=1;k1>0;k1*=2)
            if (k1>=s&&(k1-s)%6==0)
            {
          //      cout << k1 << " " << (k1-s)/6 << endl;
                ans=true;
          

posted @ 2013-08-10 21:40  为美好世界献上珂学  阅读(115)  评论(0)    收藏  举报