Uva 257: Palinwords(Hash)

来源:互联网 发布:浏览器打开知乎 编辑:程序博客网 时间:2024/05/14 18:38

首先鸣谢程大神的指点……


题意: 求一个字符串里面有几个不同的回文,可以交叉不能覆盖,大于等于两个就把那个字符串输出。


明显用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);    }}


0 0