UVA 257 Palinwords(hash)题解

思路:给你字符串,如果他包含至少两个长度大于等于3的回文,并且这些回文不能嵌套(例如aaa嵌套在aaaa,waw嵌套在awawa),如果这个字符串这么牛逼的话,就输出他。

思路:拿到字符串先正序hash和逆序hash,用来判断回文串。这里其实只要判断长度为3和4的回文就行,因为3,4大的可以嵌套在比他大的里面。一开始我还在想怎么区分aaa和aaaa,弄了个很复杂的东西,但是我发现其实只要储存回文串的半径的hash就行了!这样长度3和4也能比了。

代码:

#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<cstring>
#include<string>
#include<sstream>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define ll long long
#define ull unsigned long long
using namespace std;
const int maxn = 255+10;
const int seed = 131;
const int MOD = 100013;
const int INF = 0x3f3f3f3f;
char s[maxn];
ull ha[2][maxn],bin[maxn];
void init(){
    bin[0] = 1;
    for(int i = 1; i <= 255; i++)
        bin[i] = bin[i - 1] * seed;
}
void HASH(int len){
    ha[0][0] = 0;
    for(int i = 1; i <= len; i++)   //顺序
        ha[0][i] = ha[0][i - 1] * seed + s[i];
    ha[1][0] = 0;
    for(int i = len,j = 1; i >= 1; i--, j++)    //逆序
        ha[1][j] = ha[1][j - 1] * seed + s[i];
}
ull getsub(int l,int r,int id){
    return ha[id][r] - ha[id][l - 1] * bin[r - l + 1];
}
int main(){
    init();
    while(scanf("%s", s + 1) !=  EOF){
        int len = strlen(s + 1);
        HASH(len);
        int flag = -1;
        ull is;
        for(int i = 1; i <= len - 2; i++){
            ull suf = getsub(i, i + 1,0);   //顺序
            ull pre = getsub(len - (i + 2) + 1, len - (i + 1) + 1, 1);   //逆序
            if(suf == pre){
                if(flag == -1){
                    is = suf;
                    flag = 0;
                }
                else if(suf != is){
                    flag = -2;
                    break;
                }
            }
        }
        if(flag == -2){
            printf("%s\n", s + 1);
            continue;
        }
        for(int i = 1; i<= len - 3; i++){
            ull suf = getsub(i, i + 1,0);   //顺序
            ull pre = getsub(len - (i + 3) + 1, len - (i + 2) + 1, 1);   //逆序
            if(suf == pre){
                if(flag == -1){
                    is = suf;
                    flag = 0;
                }
                else if(suf != is){
                    flag = -2;
                    break;
                }
            }
        }
        if(flag == -2){
            printf("%s\n", s + 1);
            continue;
        }
    }
    return 0;
}

 

posted @ 2018-08-23 16:33  KirinSB  阅读(313)  评论(0编辑  收藏  举报