UVA11475:Extend to Palindrome(Hash 或 KMP)

来源:互联网 发布:四轴叶轮加工编程方法 编辑:程序博客网 时间:2024/06/11 15:42


题意:给一个字符串,在后面添加最少的字符,使它变成回文串。

思路:显然要找出后缀最长的回文子串,然后加上前面的部分即可,我们可以考虑用字符串哈希或kmp匹配,将后往前和前往后的子串匹配一下,相同的就是回文串。

①使用滚动哈希的方法,复杂度O(n)。

# include <iostream># include <cstdio># include <cstring># define ULL unsigned long longusing namespace std;int main(){    char s[100003];    while(~scanf("%s",s))    {        ULL pow=1, seed=233, pre=0, suf=0, ans;        int len = strlen(s);        for(int i=len-1; i>=0; --i)        {            suf = suf + s[i]*pow;            pow *= seed;            pre = pre*seed + s[i];            if(suf == pre)                ans = i;        }        printf("%s",s);        for(int i=ans-1; i>=0; --i)            putchar(s[i]);        printf("\n");    }    return 0;}


②KMP算法,比hash略慢。

# include <iostream># include <cstdio># include <cstring># include <algorithm>using namespace std;string s, t;int pre[100003];void init(){    pre[0] = pre[1] = 0;    for(int i=1; i<t.size(); ++i)    {        int j = pre[i];        while(j && t[j] != t[i]) j = pre[j];        pre[i+1] = t[j]==t[i]?j+1:0;    }}int main(){    while(cin >> s)    {        int j=0;        t.resize(s.size());        reverse_copy(s.begin(), s.end(), t.begin());        init();        for(int i=0; i<s.size(); ++i)        {            while(j && s[i] != t[j]) j = pre[j];            if(s[i] == t[j]) ++j;        }        cout << s << t.substr(j) << endl;    }    return 0;}



0 0
原创粉丝点击