您的位置:首页 > 其它

哈希表判断回文数的应用

2015-10-27 21:03 253 查看
.第二饭堂 (hw.pas/c/cpp)

问题描述

由于一饭班长表示各种鸭梨,美丽的*中决定历史性地启用第二饭堂。

而部分领导觉得,二饭依山傍水,环境优美,未免有不和谐的事情(你懂的)发生,决定到二饭巡视同学们用餐时的就座情况。

为了应付这一情况,同学们决定联合起来“布阵”。 方便起见,同学们已经把座位情况抽象成一个长度为n的仅含数字及字母的字符串,他们想请你帮忙算算这个字符串的和谐程度。

已知一个字符串被称为k-回文串的充要条件是它自身是回文串,并且它长为⌊n/2⌋(下取整)的前缀和后缀是(k-1)-回文串。根据定义,任意字符串(包括空串)都是0-回文串。

一个字符串的回文度数就是这个字符串的k的最大值。

而对于一个给定的字符串,它的和谐程度就是其所有前缀的回文度数之和。 你的任务就是算出这个和谐程度具体是多少。

输入

一行一个仅包含数字和字母的字符串。

输出

一行一个整数表示这个字符串的和谐高度。

输入输出样例

hw.in

abacaba

hw.out

6

数据规模

对于30%的数据字符串长度不超过1000

对于70%的数据字符串长度不超过100000

对于100%的数据字符串长度不超过5000000

首先关于和谐程度,是一个递推关系:F(x)=F(x/2)+1

但是这题一看数据就非常大,然后我还是义无反顾的暴搜了

#include<cstdio>
#include<cstdlib>
#include<cstring>

int a[5000001],h[5000001],n,l,ans;

char s[5000001];

int main()
{
int i,j;
void hw(int m);
int check(int m);

freopen("hw.in","r",stdin);
freopen("hw.out","w",stdout);

gets(s);
n=strlen(s);
h[1]=1;
ans=1;
for(i=1;i<=n;i++)a[i]=s[i-1];
for(i=2;i<=n;i++)hw(i);
for(i=2;i<=n;i++)ans=ans+h[i];

printf("%d\n",ans);

fclose(stdin);
fclose(stdout);
return 0;
}

int check(int m)
{
int p,q,f;
p=1;q=m;f=1;
while(p<=q)
{
if(a[p]!=a[q])f=0;
p++;q--;
}
return f;
}

void hw(int m)
{
if (check(m)==0)h[m]=0;
else h[m]=h[m/2]+1;
}


这样的话可以过七个点,主要时间是花在判断回文上。如何才能更有效更快的判断回文?我也不知道。

#include <iostream>
#include <cstdio>

using namespace std;

char s[5000010];
int f[5000010];

int main(){
freopen("hw.in","r",stdin);
freopen("hw.out","w",stdout);
scanf("%s", s);
int l=0, r=0, e=1, ans=0;
for (int i=0; s[i]; i++){
l=l*107+s[i];
r=r+s[i]*e; e*=107;
if (l==r) f[i+1]=f[(i+1)/2]+1;
ans+=f[i+1];
}
cout<<ans<<endl;
return 0;
}


以上就是传说中的标程,用了散列表hash来判断回文,具体怎么判断,你懂得(我也不知道)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: