天天看點

Uva 257: Palinwords(Hash)

首先鳴謝程大神的指點……

題意: 求一個字元串裡面有幾個不同的回文,可以交叉不能覆寫,大于等于兩個就把那個字元串輸出。

明顯用HASH。。。本來以為要求每個字母對應的的所有的hash。。。判斷回文還需要正一遍hash 反一遍hash 的 ……然後程大神告訴我隻需要看三個字母的或者四個字母的有幾個就行……因為大于等于五個的,比如五位長度的回文字元串,裡面必然包含了三位長度的回文……

這樣就很簡單了,甚至判斷是否回文都可以暴力解決……

但是我特麼就不懂了!!!hash基數選擇26能過!!!媽蛋的選38就不能過!!!

AC Memory : 0MS   Time : 22MS

代碼:    (PS.請無視我的變量命名……)

#include<cstdio>
#include<cstring>

using namespace std;

int p1,p2,times=233;
int fuck[1000000];
char str[300];

bool ss()
{
    times++;
    if(times>=1000000000)
    {
        times=1;
        memset(fuck,0,sizeof(fuck));
    }
    int len=strlen(str);
    int ha;
    int ans1=0,ans2=0,shit;
    for(int i=1;i<=len-2;i++)
    {
        if(str[i-1]==str[i+1])
        {
            shit=(str[i-1]-'A')*26*26+(str[i]-'A')*26+(str[i+1]-'A');
            if(fuck[shit]==times)
            continue;
            ans1++;
            fuck[shit]=times;
            p1=i;
        }
    }
    if (ans1>1)
        return true;
    for(int i=1;i<=len-3;i++)
    {
        if(str[i-1]==str[i+2] && str[i]==str[i+1])
        {
            shit=(str[i-1]-'A')*26*26*26+(str[i]-'A')*26*26+(str[i+1]-'A')*26+(str[i+2]-'A');
            if(fuck[shit]==times)
                continue;
            ans2++;
            fuck[shit]=times;
            p2=i;
        }
    }
    if(ans2>1)
        return true;
    if (ans1==1 && ans2==1)
    {
        if (p2<=p1 && p1<=(p2+1))
            return false;
        else
            return true;
    }
    return false;
}
int main()
{
    while (~scanf("%s",str))
    {
        if (ss())
            printf("%s\n",str);
    }

}