UESTC 1703 一道更简单的字符串题 哈希+枚举

来源:互联网 发布:matlab定义数组 编辑:程序博客网 时间:2024/05/20 21:24

一道更简单的字符串题

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)


Submit  Status
有一天,潘爷在白纸上写了字符串A,然后他不断的重复写这个字符串A,于是白纸上出现了一个新的字符串:AAAAAAAA....。现在我从这个字符串的两个不同的位置截取了一段字符串叫做B,现在给你这个字符串B,你能告诉我潘爷可能写的最短的字符串A有多长吗。举个例子,A=“abcdefg”,我获得的字符串是 abcd efgabcdefgabcde fgabcdefg..... ,现在我把红色的部分“efgabcdefgabcde”作为B,你需要找到最短的符合条件的字符串A的长度。


Input

输入包括一个字符串B,长度不大于1000000;


Output

对于每组数据,输出一个整数,代表最短的字符串A的长度。


Sample input and output

Sample Input Sample Output
efgabcdefgabcde     7


Source

2017 UESTC Training for Search Algorithm & String

UESTC 1703 一道更简单的字符串题


My Solution

求出最小循环串。

哈希+枚举
先把字符串哈希,
然后从ans = 1 ~ n进行枚举,
check的时候枚举每个hash(i, ans) == hash(0, ans),
且对于最后一段长度不到ans的 hash(i, len-i) == hash(0, len-i),
因为是从小到大枚举,所以一旦有ans满足,则就是答案。
这是一个调和级数,故nlin(n)。
时间复杂度 O(nlin(n))
空间复杂度 O(n)


#include <iostream>#include <cstdio>#include <cstring>using namespace std;typedef unsigned long long ull;const int MAXN = 1e6 + 8;const ull p = 1e12 + 7;             //!struct HASH{    ull Hash[MAXN], xp[MAXN];    void init1(int sz){        xp[0] = 1;        for(int i = 1; i <= sz; i++) xp[i] = xp[i-1] * p;    }    void init2(char *s){//0~n-1 based        int sz = strlen(s);        Hash[sz] = 0;        for(int i = sz - 1; i >= 0; i--){            Hash[i] = Hash[i+1] * p + (s[i] - 'a' + 1);        }    }    ull get_Hash(const int& st, const int& len){        return Hash[st] - Hash[st + len] * xp[len];    }} hh;char s[MAXN];int len;inline bool check(int x){    for(int i = x; i < len; i += x){        if(len - i >= x){            if(hh.get_Hash(i, x) != hh.get_Hash(0, x)){                return false;            }        }        else{            if(hh.get_Hash(i, len - i) != hh.get_Hash(0, len - i)){                return false;            }        }    }    return true;}int main(){    #ifdef LOCAL    freopen("d.txt", "r", stdin);    //freopen("d.out", "w", stdout);    int T = 4;    while(T--){    #endif // LOCAL    //ios::sync_with_stdio(false); cin.tie(0);    scanf("%s", s);    len = strlen(s);    hh.init1(len);    hh.init2(s);    int ans = 0, i;    for(i = 1; i <= len; i++){        if(check(i)){            ans = i;            break;        }    }    printf("%d\n", ans);    #ifdef LOCAL    cout << endl;    }    #endif // LOCAL    return 0;}


  Thank you!

                                                                                                                                            ------from ProLights

原创粉丝点击