Hash欢乐赛
来源:互联网 发布:linux运行java jar包 编辑:程序博客网 时间:2024/04/29 03:23
Hash欢乐赛总结
今天终于把Hash欢乐赛所有的题目都A了,Hash真的是一个靠RP的东西,一些题目我只写了单关键字而且没有挂链,结果还是靠着RP A了,也只能说运气好吧,但Hash确实非常实用,能使不少难题用简单的Hash骗到不少分甚至AC。
Problem 1
串匹配【str1.pas/c/cpp】
Description
给1定一个字符串S1~Sn,给定一个匹配串 s1~sm,求有多少匹配子串。
Input 【str1.in】
第一行两个数字:n,m
第二行一个字符串S1~Sn
第三行一个字符串s1~sm
Output 【str1.out】
一个数字,表示有多少匹配子串
Sample Input
5 2
ababa
ba
Sample Output
2
Score:
n<=5000000,m<=50,m<n
保证所有字符均为小写英文字符
Description
给1定一个字符串S1~Sn,给定一个匹配串 s1~sm,求有多少匹配子串。
Input 【str1.in】
第一行两个数字:n,m
第二行一个字符串S1~Sn
第三行一个字符串s1~sm
Output 【str1.out】
一个数字,表示有多少匹配子串
Sample Input
5 2
ababa
ba
Sample Output
2
Score:
n<=5000000,m<=50,m<n
保证所有字符均为小写英文字符
【分析】这是一道比较水的Hash,关键是选一个好的值Mod,用双关键字是问题不大,但单关键字也能靠着RP A掉,我比较懒,就写了个单关键字Hash,把字母转成26进制数,过程中MOd mo,只要O(N)的效率便可求出解。在Hash的变化中,可以用DDTT讲到的O(1)的方法,删掉第一个数,添加最后一个数。但删数和添加也要注意技巧,如果删的是最后一个,添加的是第一个,那么就需要除,然而Mod过特殊值,因此除会有误差,从而会导致WA,因此我们调整一下方法,删除第一个数,乘以26后加上最后一个数,这样就不会WA了。
【代码】
#include<cstdio>#include<cstring>#include<cstdlib>#define mo 9797797int i,j,l,n,m,o,p,a[mo],k,k1,o1;char ch[5000001],ch1[51];int main(){ freopen("str.in","r",stdin); freopen("str.out","w",stdout); scanf("%d%d",&n,&m); scanf("%s",ch); scanf("%s",ch1); k=1; o=0; o1=0; m--;n--; for(i=m;i>=0;i--) { o=(o+(ch[i]-'a')*k)%mo; o1=(o1+(ch1[i]-'a')*k)%mo; if(i>0)k=k*26%mo; } a[o]++; for(i=m+1;i<=n;i++) { o=(o-(ch[i-m-1]-'a')*k%mo+mo)%mo; o=(o*26+(ch[i]-'a'))%mo; a[o]++; } printf("%d\n",a[o1]); //system("pause");}
Problem 2
基因【orzrzz.pas/c/cpp】
Description
由于RZZ 实在是太强了,引起了 YZH对RZZ 表示无限崇敬。
一天YZH再次被 RZZ 虐得体无完肤,于是开始抱怨自己的基因遗传不好,
想要和RZZ 对比基因的类似程度,如果非常相似,YZH会非常开心,如果差异
很大,YZH会变得非常郁闷,由于YZH 太忙了,没有时间去搞这种东西,于是
把这个问题留给了你。
基因匹配需要满足以下条件:它们的最长前缀的长度等于两者中较短者的长
度。
现在给定了N个RZZ 的基因和 M 个YZH 的基因,要求找出每一个 YZH基
因与多少个RZZ 基因相匹配。
Input 【orzrzz.in】
第一行两个数字:N,M
下面N行,每行开头一个数字len,接下来是一个长度为len 的RZZ 基因
下面M 行,每行开头一个数字len,接下来是一个长度为len 的 YZH 基因
Output 【orzrzz.out】
M 行,表示每一个YZH基因与多少个RZZ 基因相匹配。
Sample Input
4 5
3 0 1 0
1 1
3 1 0 0
3 1 1 0
1 0
1 1
2 0 1
5 0 1 0 0 1
2 1 1
Sample Output
1
3
1
1
2
数据范围与约定: 100%的数据,M<=50000,N<=50000,len<=10000,保证读入不超时
Description
由于RZZ 实在是太强了,引起了 YZH对RZZ 表示无限崇敬。
一天YZH再次被 RZZ 虐得体无完肤,于是开始抱怨自己的基因遗传不好,
想要和RZZ 对比基因的类似程度,如果非常相似,YZH会非常开心,如果差异
很大,YZH会变得非常郁闷,由于YZH 太忙了,没有时间去搞这种东西,于是
把这个问题留给了你。
基因匹配需要满足以下条件:它们的最长前缀的长度等于两者中较短者的长
度。
现在给定了N个RZZ 的基因和 M 个YZH 的基因,要求找出每一个 YZH基
因与多少个RZZ 基因相匹配。
Input 【orzrzz.in】
第一行两个数字:N,M
下面N行,每行开头一个数字len,接下来是一个长度为len 的RZZ 基因
下面M 行,每行开头一个数字len,接下来是一个长度为len 的 YZH 基因
Output 【orzrzz.out】
M 行,表示每一个YZH基因与多少个RZZ 基因相匹配。
Sample Input
4 5
3 0 1 0
1 1
3 1 0 0
3 1 1 0
1 0
1 1
2 0 1
5 0 1 0 0 1
2 1 1
Sample Output
1
3
1
1
2
数据范围与约定: 100%的数据,M<=50000,N<=50000,len<=10000,保证读入不超时
【分析】这其实是一道字母树的题目,但由于只有0,1两个数,因此可以往左往右建树。如果是0,就往左查找、建树,如果是1,就往右查找、建树。在建树的过程中,对于每个节点k,都将down[k]+1,因为如果在搜索一个字符串的时候,能走完,就说明下面的所有节点的字符串都能和该基因匹配,当然走过的路径中有字符串节点也能匹配;不能走完,说明不能走下去了, 就不能加下面的所有节点,这题就很简单了。
【代码】
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>using namespace std;int i,j,k,m,n,o,p,down[800000],a[800000],lef[800000],righ[800000],f[800000],len,cnt,now;int main(){ freopen("orzrzz.in","r",stdin); freopen("orzrzz.out","w",stdout); scanf("%d%d",&n,&m); memset(lef,0,sizeof(lef)); memset(righ,0,sizeof(righ)); cnt=1; for(i=1;i<=n;i++) { scanf("%d",&len); now=1; down[now]++; for(j=1;j<=len;j++) { scanf("%d",&o); if(o==0){if(lef[now]==0)lef[now]=++cnt;now=lef[now];down[now]++;} if(o==1){if(righ[now]==0)righ[now]=++cnt;now=righ[now];down[now]++;} } f[now]++; } for(i=1;i<=m;i++) { bool flag=false; int ans=0; scanf("%d",&len); now=1; for(j=1;j<=len;j++) { scanf("%d",&o); if(!flag)ans+=f[now]; if(o==0&&!(flag)){if(lef[now]==0)flag=true;now=lef[now];} if(o==1&&!(flag)){if(righ[now]==0)flag=true;now=righ[now];} } if(!flag)ans+=down[now]; printf("%d\n",ans); } //system("pause"); return 0;}
0 0
- Hash欢乐赛
- 7.26 机房欢乐赛 T1 无尽的矩阵 (hash + KMP)
- 寒假欢乐赛
- 欢乐赛总结
- 欢乐
- 【PYC#1 欢乐赛】 题解
- 8-2情人节欢乐赛
- PYC#1欢乐赛第三题题解
- 【2015.12.25】圣诞节欢乐赛赛后分析
- 机房水题欢乐赛 20160216
- 校内欢乐赛之爆零季 POJ 1904
- 校内欢乐赛之爆零季 T2
- 百度杯2017年春秋欢乐赛
- NOIP 模拟 机房欢乐WAK赛
- 2017长乐国庆欢乐赛Day1
- 【2017十月欢乐赛Day2】subset
- Codeforces Round #219 (Div. 2) + 元旦欢乐赛
- 2014.8.3情人节欢乐赛【Benny的农场】
- ORACLE 11G RAC常用操作(维护及管理)
- 如何在DataTable中添加表、列字段?NewRow()【下】
- CString 成员函数用法大全(高)
- MMU的作用
- 三个重要的同余式——威尔逊定理、费马小定理、欧拉定理 + 求幂大法的证明
- Hash欢乐赛
- Android 图片的浏览、缩放、拖动和自动居中
- C/C++指令 #undef ,#ifdef, #ifndef,#if的用法
- C#:USB设备枚举(二)设备枚举API
- 也谈Android中的Context(1)
- 基于 GVim 的 C/C++ IDE -- VimLite 介绍
- 项目开始编码前应确认哪些信息?
- 如何在Linux下格式化U盘以及修改卷标
- Microsoft Excel 2010错误:"此工作簿包含嵌入对象。Microsoft Excel 可能无法从这些对象中删除个人信息。"