hdu4662 简单搜索打表

题意:
     给你一个初始串"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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值