哈希表判断回文数的应用
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
但是这题一看数据就非常大,然后我还是义无反顾的暴搜了
这样的话可以过七个点,主要时间是花在判断回文上。如何才能更有效更快的判断回文?我也不知道。
以上就是传说中的标程,用了散列表hash来判断回文,具体怎么判断,你懂得(我也不知道)。
问题描述
由于一饭班长表示各种鸭梨,美丽的*中决定历史性地启用第二饭堂。
而部分领导觉得,二饭依山傍水,环境优美,未免有不和谐的事情(你懂的)发生,决定到二饭巡视同学们用餐时的就座情况。
为了应付这一情况,同学们决定联合起来“布阵”。 方便起见,同学们已经把座位情况抽象成一个长度为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来判断回文,具体怎么判断,你懂得(我也不知道)。
相关文章推荐
- Unity3D内部脚本编程入门
- 银行就好系统,该程序存在问题,在顾客进入窗口开始服务的时候,一号窗口会出现在后面开始服务,如果有解决方案,请告诉我谢谢!
- nyoj96
- Jmeter之Bean shell使用(一)
- iOS开发-NSDate使用
- 制作loop档案
- 打包上传报错!!ERROR ITMS-90049:"This bundle is invalid. The bundle identifier contains disallowed characte
- next-key lock (glap lock)完全解析.
- 杭电2576
- 阶乘算法全集,阶乘末尾非零位,阶末尾零的个数
- PHP会话处理——Cookie和Session
- 【作业】实现miniVector
- Thinkphp学习笔记1-URL模式
- 在用FragmentController类管理Fragment时报的RutimeError
- json知识详解
- jsp中的c:foreach基本用法
- MAC OS真正提权,告别rootless
- [BZOJ 1003] 物流运输 SPFA+DP
- OC字符串常用函数
- java第五章 子类与继承