0
点赞
收藏
分享

微信扫一扫

hdu4662 简单搜索打表

ivy吖 2022-07-18 阅读 26

题意:
     给你一个初始串"MI",这个串有三种操作,
(1)M后卖弄可以直接复制 ,MI -> MII
(2)三个III可以变成一个U,MUIII -> MUU
(3)连续的两个U可以直接删除,MIUUU -> MIU
每次输入一个字符串,问你这个字符串是不是MI变过来的.
 
思路:

     刚开始想都没想直接开个容器mark,然后搜索打表,控制的长度是1000000,直接敲完运行等了好几分钟都没打完,哎! sb了,后来仔细看了看题目发现 其实我们可以这样想,所有的U都是i经过一线变化过来的,因为刚开始的时候没有U,而i能变成u而u不能变成i,还有的就是这个串一定是开头是M,因为没有操作能让中间产生m,或者把M变没,这样就简单了,那么就相当于一开始有一个i,我们可以把i的个数*2(操作1) 或者把i的个数-6 (操作3),这样所有的可能i的个数都打出来,没多少1--300000个,对于输入的串我们先看下是不是只有开头有一个M,然后在统计下他有多少个i,一个u是三个i(还原操作2),然后根据当前的i的数量是否被mark输出Yes或者No,水题一枚.



#include<stdio.h>
#include<string.h>

#define N 1000100

char str[N];
int mark[N*3];

void DFS(int s)
{
mark[s] = 1;
if(s * 2 <= N * 3 && !mark[s * 2])
DFS(s * 2);
if(s - 6 >= 1 && !mark[s - 6])
DFS(s - 6);
}

int main ()
{
memset(mark ,0 ,sizeof(mark));
DFS(1);
int L ,ms ,t ,sum;
scanf("%d" ,&t);
while(t--)
{
scanf("%s" ,str);
L = strlen(str);
ms = sum = 0;
for(int i = 0 ;i < L ;i ++)
{
if(str[i] == 'M') ms ++;
if(i)
{
if(str[i] == 'I')
sum ++;
else sum += 3;
}
}
if(ms != 1 || str[0] != 'M' || !mark[sum])
puts("No");
else puts("Yes");
}
return 0;
}




举报

相关推荐

0 条评论