• HDU 3746 Cyclic Nacklace kmp找循环节


    给出一个串,每次只能在首端或尾端加入字符,问至少要加入多少个字符,才能使得这个串为循环串(由出现次数大于等于2的循环节构成)

    100组数据 每组数据字符串长度不超过1e5

    sol:

    在头部加和在尾部加其实是一样的,设原始串的长度为len,则有

    (s[0..fail[len-1]]=s[(len-1-fail[len-1])..len-1])

    若s本身已经是循环串了,用字母a表示一个循环节,那么s可以表示为aaaaa...aaaaa

    那么根据fail数组的定义,len-1-fail[len-1]将会等于最小循环节的长度。可以用这个值能否整除len判断原串是否是循环串,即len%(len-1-fail[len-1])=0是s为循环串的充要条件。

    必要性显然,充分性证明如下:

    考虑反证法

    若s本身不是循环串,那么s可以看作是最小循环节重复x次加上其部分前缀构成的。

    那么s可以表示为循环节的前缀+循环节的后缀+x-1次循环节+循环节的前缀

    fail[len-1]+1为最后俩部分的长度,k=len-1-fail[len-1]为循环节的长度。

    那么k*x-fail[len-1]-1为要补的长度

    那么对于这题,当s为循环串时输出0即可。否则,补齐第二个前缀剩下的部分,也就是循环节的剩余部分即可。

    注意第四第五部分的长度可能为0,此时答案为len。

    // Problem: Cyclic Nacklace
    // Contest: Virtual Judge - HDU
    // URL: https://vjudge.net/problem/HDU-3746#author=0
    // Memory Limit: 32 MB
    // Time Limit: 1000 ms
    // 
    // Powered by CP Editor (https://cpeditor.org)
    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 7;
    #define ll long long
    int rd() {
        int s = 0, f = 1; char c = getchar();
        while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
        while (c >= '0' && c <= '9') {s = s * 10 + c - '0'; c = getchar();}
        return s * f;
    }
    int len;
    char s[maxn];
    int fail[maxn];
    void getfail() {
    	int match = -1;
    	fail[0] = -1;
    	for (int i = 1; i < len; i++) {
    		while (match >= 0 && s[match+1] != s[i]) {
    			match = fail[match];
    		}
    		if (s[match+1] == s[i]) {
    			match++;
    		}
    		fail[i] = match;
    	}
    	//for (int i = 0; i < len; i++) printf("fail[%d]==[%d]
    ", i, fail[i]);
    }
    int main() {
    	int T = rd();
    	while (T--) {
    		scanf("%s", s);
    		len = strlen(s);
    		//for (int i = 0; i < len; i++) fail[i] = -1;
    		getfail();
    		int k = len - fail[len-1] - 1;
    		//printf("k == %d len == %d fail[k-1] == %d fail[len - 1] == %d
    ", k, len, fail[k-1], fail[len-1]);
    		if (len % k == 0 && len != k) {
    			puts("0");
    		} else printf("%d
    ", len/k*k-fail[len-1]-1);
    	}
    }
  • 相关阅读:
    mysql性能调优
    java面试大全
    JVM调优总结
    大数据行业跳槽面试前你需要做什么
    什么是分布式锁?实现分布式锁的方式
    如何保障mysql和redis之间的数据一致性?
    数据倾斜的原因和解决方案
    hive优化
    c# 系统换行符
    12种增强CSS技能并加快开发速度的资源
  • 原文地址:https://www.cnblogs.com/YjmStr/p/15417390.html
Copyright © 2020-2023  润新知