HDU 4662 MU Puzzle (2013多校6 1008 水题)

MU Puzzle

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 134    Accepted Submission(s): 71

Problem Description 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  

 

Source
2013 Multi-University Training Contest 6  

 

Recommend zhuyuanchen520           全场最水的题目。     一开始时MI。 其实可以全部转化成I的个数。   一个U相当于3个I,减少两个U,相当于减少6个I。   第一个操作相当于可以把I的个数翻倍。     所以1个I,2个I,4个I,8,16,32,。。。。这些2^n个I都是可以实现的。     而且可以减掉6个I,8-6=2,16-6=10,10-6=4,等等都可以。   10个I可以,20个I也可以。     这样数I的个数,比赛时候暴力预处理下所以可以的情况,就像晒素数一样。       其实可以发现规律的,除了一个I之外,奇数个I和个数被6整除的都不行,可以根据整除性分析下。               贴上代码,里面有一个init函数式预处理的,虽然没有用上      

 1 /*
 2  * Author:  kuangbin
 3  * Created Time:  2013/8/8 11:54:08
 4  * File Name: 1008.cpp
 5  */
 6 #include <iostream>
 7 #include <cstdio>
 8 #include <cstdlib>
 9 #include <cstring>
10 #include <cmath>
11 #include <algorithm>
12 #include <string>
13 #include <vector>
14 #include <stack>
15 #include <queue>
16 #include <set>
17 #include <time.h>
18 using namespace std;
19 char str[1000010];
20 const int MAXN = 3000010;
21 bool dp[MAXN];
22 bool vis[MAXN];
23 void init()
24 {
25     memset(dp,false,sizeof(dp));
26     memset(vis,false,sizeof(vis));
27     dp[1] = true;
28     queue<int>q;
29     q.push(1);
30     vis[1] = true;
31     while(!q.empty())
32     {
33         int tmp = q.front();
34         dp[tmp] = true;
35         q.pop();
36         if(tmp == 0){dp[0] = true;vis[0] = true;continue;}
37         if(tmp >= 6 && !vis[tmp-6])
38         {
39             q.push(tmp-6);
40             vis[tmp-6] = true;
41         }
42         tmp *= 2;
43         while(tmp < MAXN)
44         {
45             if(vis[tmp])break;
46             dp[tmp] = true;
47             if(tmp >= 6 && !vis[tmp-6])
48             {
49                 q.push(tmp-6);
50                 vis[tmp-6] = true;
51             }
52             tmp *= 2;
53         }
54     }
55 }
56 
57 
58 int main()
59 {
60     int T;
61     init();
62     scanf("%d",&T);
63     while(T--)
64     {
65         bool flag = true;
66         scanf("%s",str);
67         int len = strlen(str);
68         if(str[0]!='M')
69         {
70             printf("No\n");
71             continue;
72         }
73         int cnt = 0;
74         for(int i = 1;i < len;i++)
75         {
76             if(str[i]=='M')
77             {
78                 flag = false;
79                 break;
80             }
81             if(str[i] =='I')cnt++;
82             else cnt+= 3;
83         }
84         if(!flag)
85         {
86             printf("No\n");
87             continue;
88         }
89         if(cnt == 1)
90         {
91             printf("Yes\n");
92             continue;
93         }
94         if(cnt%2 == 1 || cnt%6 == 0)printf("No\n");
95         else printf("Yes\n");
96     }
97     return 0;
98 }

 

                                           

 

 

 

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/kuangbin/p/3246467.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞