kmp(二)

Cyclic Nacklace HDU - 3746

题目链接:https://cn.vjudge.net/contest/163024#problem/D
题目大意:给你一个字符串,要求将字符串的全部字符最少循环2次需要添加的字符数。
例子:abcabc 已经循环2次,添加数为0
abcac 没有循环2次,添加字符abcac。数目为5.
abcabcab 已经循环过2次,但第三次不完整,需要添加数为1
题目分析:求循环节

      get_next();
      int min_repeat = len - Next[len - 1]; //最小循环节
      if(len % min_repeat == 0 && len / min_repeat > 1) //len / min_repeat 是为了防止一个字符的情况
      //if(len- (len - nexts[len]) > 0 && len%min_repeat==0) 也是对的
              printf("0\n");
      else
         printf("%d\n", min_repeat - (len % min_repeat));

为什么len - Next[len - 1]是最小循环节?
因为abcefgabc Next[len - 1] = 3,这是后缀与前缀的最大匹配个数,说明从abc又开始循环了,所以len - Next[len - 1]是循环节。
abcabcabcab 这种我也不懂怎么解释。
这里的循环节是说它应该的循环节,而不是说它真正的循环节。

Period HDU - 1358

题目链接:https://cn.vjudge.net/contest/163024#problem/E
题目大意:求字符串的前缀是否为周期串,若是,打印循环节的长度及循环次数;
题目分析:遍历每一个位置,判断循环节即可
例子:
3
aaa
Test case #1
2 2
3 3

12
aabaabaabaab
Test case #2
2 2
6 2
9 3
12 4

int main()
{
     int cas = 1, i;
     while(~scanf("%d", &len) && len)
     {
        scanf("%s", s);
        get_next();
        printf("Test case #%d\n", cas++);
        for(i = 1; i <= len; i++)
        {
            int min_repeat = i - Next[i - 1];
            if(i % min_repeat == 0 && i / min_repeat > 1)
                printf("%d %d\n", i, i / min_repeat);
        }

        printf("\n");
     }
     return 0;
}

Seek the Name, Seek the Fame POJ - 2752

题目链接:https://cn.vjudge.net/contest/163024#problem/H
题目分析:给定一个字符串s,从小到大输出s中既是前缀又是后缀的子串的长度。
例子: input :ababcababababcabab output: 2 4 9 18

int main()
{
    int i;
     while(~scanf("%s", s)) {
         len = strlen(s);
         get_next();

         int cnt = 0;
         int t = Next[len - 1];
         ans[cnt++] = len;
         while(t > 0) {
           if(s[len - 1] == s[t - 1]) {
              ans[cnt++] = t;
           }
           t = Next[t - 1];
       }
        for(i = cnt - 1; i >= 0; i--)
            printf("%d%c", ans[i], i == 0 ? '\n' : ' ');
     }
     return 0;
}

Count the string HDU - 3336

题目链接:https://cn.vjudge.net/contest/163024#problem/K
题目大意:给定一字符串,求该串的前缀在该串中的出现次数。
题目样例:
1
4
abab “a”出现l两次, “ab”出现两次, “aba”一次, “abab”一次 2+2+1+1 = 6
题目分析:
举个例子。
abababa**b**cab
00123456012
依旧是next数组的应用,首先每个前缀一定会出现一次,一共有n个。
当next[i] + 1 != next[i + 1] 时,就说明到这个位置,和前缀能匹配上,例子中b位置断开,Next[b] = 6,说明从当前位置向前六个跟前缀一样,就是说有六个前缀又出现了一次,这时候sum+= Next[b]。

int main()
{
    int t, n, i, sum;
    scanf("%d", &t);
    while(t--)  {
        scanf("%d", &n);
        scanf("%s", str);
        get_next();

        sum = n + Next[n - 1];
        sum %= 10007;
        for(i = 0; i < n - 1; i++) {
            if(Next[i] + 1 != Next[i + 1]) {
                sum += Next[i];
                sum %= 10007;
            }

        }

        printf("%d\n", sum % 10007);
    }
     return 0;
}
阅读更多
上一篇吉哥系列故事――恨7不成妻 HDU - 4507
下一篇Simpsons’ Hidden Talents HDU - 2594 (kmp)
想对作者说点什么? 我来说一句

KMP最经典版本2.9.3.1428版

2012年04月26日 13.47MB 下载

非常漂亮的KMP皮肤

2008年10月28日 634KB 下载

KMP关联图标(带说明和预览图)

2010年01月26日 6.21MB 下载

KMP、Mancher和扩展KMP算法详解

2016年08月08日 123KB 下载

kmp算法实现

2012年10月29日 1KB 下载

kmp算法代码

2014年06月28日 2KB 下载

kmp 匹配算法

2008年06月26日 705B 下载

没有更多推荐了,返回首页

关闭
关闭