• hdu 3746 Cyclic Nacklace


    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=3746

    题意就是给出一个字符串,让你可以在左边或者右边添加一定数量(输出最小数量)的字符使其可以成为一个有循环的最小长度的圆,

    不可以从中间插入字符,因为最终是要连接成一个圆,所以无论从左边还是右边添加最后效果都是一样的,下面考虑从右面开始添加

    这题主要是对KMP中next数组的应用,另外还有循环节的小技巧

    假设字符串长度为len,那么求出next[len]即为该串后缀与前缀的最大匹配数,那么需要构成最小长度圆的循环节长cir=len-next[len];

    所以说当len%cir==0 && len!=cir是表示该串无需要添加任何字符则可以构成符合条件的圆环

    反之则需要添加一定数量的字符,添加最少数量为cir-(next[len]%cir)

    这题很不理解用算法导论上那种求next数组的方法为什么会超时,AC的代码是采用的网上找来的球next数组的方法,用着也很不错

    代码如下

    View Code
     1 # include <stdio.h>
     2 # include <string.h>
     3 int next[100010];
     4 int len;
     5 int COUNT_next(char *str)
     6 {
     7    int i=0,j=-1;
     8    next[0]=-1;
     9    while(i<len)
    10    {
    11        if( j==-1 || str[i] == str[j] )
    12         {
    13             ++i;
    14             ++j;
    15             next[i] = j;
    16         }//每当自增i和j,得到一个新的next[i]
    17         else j = next[j];//模式串向右移动
    18    }
    19 
    20 }
    21 int main()
    22 {
    23     int n, cir;
    24     char str[100010];
    25     scanf("%d",&n);
    26     while(n--)
    27     {
    28         scanf("%s", str);
    29         len = strlen(str);
    30         memset(next,0,sizeof(next));
    31         COUNT_next(str);
    32         cir=len - next[len];
    33         //printf("%d~\n",next[len]);
    34         if(len%cir==0 && len != cir) printf("0\n");
    35 
    36         else printf("%d\n",cir-(next[len]%cir));
    37     }
    38     return 0;
  • 相关阅读:
    java反序列化盲打与手工测试
    centos7下面利用服务启动empire后门的方法
    部分APP无法代理抓包的原因及解决方法(flutter 应用抓包)
    代码审计入门之Jeeplus代码审计
    代码审计新手入门-xdcms_v1.0
    Web应用安全模糊测试之路
    java代码审计文章集合
    Java框架级SSM代码审计思路
    [翻译] 使用Frida来hack安卓APP(一)
    基于Websocket接口的SQL注入利用
  • 原文地址:https://www.cnblogs.com/sunshinecyh/p/3029159.html
Copyright © 2020-2023  润新知