• HDU-3746-Cyclic Nacklace


    其实len-next[len]的意思是,原串的长度-前面重复串的长度=不重复串的长度。
    放张严蔚敏老师的写法:
    在这里插入图片描述
    最后一个数字才是next[len](自己手演,只讲式子)
    第一个串:aaa,前面重复的是aa,然后减去之后只剩下a,长度为1。
    第二个串:abca,next[4]=1,把第一个a去掉,后面的是bca,是不重复的。
    第三个串:abcde,没有可以去的,自己就是最短循环节。
    再放一张图:
    在这里插入图片描述
    next[12]=7,前面重复的为7,去掉之后剩下cdeab。其实这句话应该这么讲,前面重复到了7,所以我们就把重复的去掉,然后就得到了最短的,不重复的一个循环节。

    再来看下改进版next的求法:
    在这里插入图片描述
    它只是对于有些已经相同的子串,我们没有必要再跳回比较了,直接跳到开头重新匹配,改进的是这个地方,它并不影响前面重复到几的值。
    还有这个:
    在这里插入图片描述
    next[len]的意思就是前面重复到几,我们把它删掉就剩下了不重复的。
    求补串的时候,要取一个模,大家可以找其它博客体会这句话。

    #include <cstdio>
    #include <cstring>
    char s[100005];
    int next[100005];
    
    void getnext()
    {
        next[0] = -1;
        int len = strlen(s);
        int j = 0, k = -1;
        while (j<=len) {
            if (k==-1||s[j]==s[k]) {
                if (s[++j]==s[++k])
                    next[j] = next[k];
                else
                    next[j] = k;
                // next[++j] = ++k;
            }
            else
                k = next[k];
        }
    }
    
    int main()
    {
        int t;
        scanf("%d", &t);
        while (t--) {
            scanf("%s", s);
            getnext();
            int len=strlen(s);
            if (next[len]&&len%(len-next[len])==0)
            	printf("0
    ");
            else 
            	printf("%d
    ",len-next[len]-next[len]%(len-next[len]));
            // for (int i = 0; i <= strlen(s);i++)
            //     printf("%d ", next[i]);
            // printf("
    ");
        }
        return 0;
    }
    
    
  • 相关阅读:
    php报错Warning: Use of undefined,开启或关闭display_errors
    easyui中dialog的使用
    easyUI布局panel面板
    git放弃本地,强制拉取远程
    友链
    CASIAWebMaskedFace 模拟佩戴口罩人脸数据集
    二叉树[先中后序 广度深度优先]
    TreePrint打印树结构工具类
    跨域设置
    和供应商开会2问题和改进
  • 原文地址:https://www.cnblogs.com/xyqxyq/p/10397187.html
Copyright © 2020-2023  润新知