POJ3274(哈希)

第一篇博客emmm

根据kuangbin   dalao的poj刷题指南做的

一道不是很简单的哈希题目

题意是求特征之和相同的第i头牛到第j头牛的max(j-i)

一开始是没有思路的,苦思冥想半天

然后(看了题解以后)手推公式:

num[i][1]+...+num[j][1]=num[i][2]+....+num[j][2]=num[i][k]+...+num[j][k];

①num[i][1]+...+num[j][1]=num[i][k]+...+num[j][k];

②sum[i][k]=sum[i-1][k]+num[i][k];

①,②=>sum[j][k]-sum[i][k]=sum[j][0]-sum[i][0];

=>sum[j][k]-sum[j][0]=sum[i][k]-sum[i][0];

所以对于sum矩阵,每个元素减去第一列

然后求sum矩阵相同的行的最大距离即可

二进制转化成k进制作为哈希值。

自己踩的坑如下:

(1)mod余数越界,调了好久

(2)矩阵每列元素减去第一列元素会导致最后的hash值可能是负的,要用abs把它变成正数

(3)search的时候不要找到就直接返回j值,要找到最后一个满足cmp的j值,因为前向星是倒着存的,而我们要的是最靠前的j值,越靠前,对于当前i值来说,距离越大,所以最晚出现的值是符合条件的

(4)脑残错误:

1for(int i=1;i<=n;i++) 2 71 { 3 73 for(int j=1;j<=k;j++) 4 74 { 75 num[i][j]-=num[i][1];//天真地以为这样就减去第一列了,当j=1执行后,num[i][1]已经 等于0了。。。还傻fufu调了半天(逃。。。。) 77 } 78 } 5 6 1 #include<iostream> 7 2 #include<cstdio> 8 3 #include<cstring> 9 4 #include<cstring> 10 5 #include<algorithm> 11 6 using namespace std; 12 7 const int mod=1000007; 13 8 const int maxn=1000009; 14 9 int n,k,cnt; 15 10 int num[1000100][31],head[1000100]; 16 11 struct node 17 12 { 18 13 int num[31]; 19 14 int next; 20 15 int p; 21 16 }edge[maxn]; 22 17 void ins(int *num,int h,int p) 23 18 { 24 19 for(int i=1;i<=30;i++) 25 20 edge[cnt].num[i]=num[i]; 26 21 edge[cnt].p=p; 27 22 edge[cnt].next=head[h]; 28 23 head[h]=cnt++; 29 24 } 30 25 bool cmp(int *num1,int *num2) 31 26 { 32 27 for(int i=1;i<=k;i++) 33 28 if(num1[i]!=num2[i]) return 0; 34 29 return 1; 35 30 } 36 31 int search(int *num,int h) 37 32 { 38 33 int flag=0,ans=0; 39 34 for(int i=head[h];i!=-1;i=edge[i].next) 40 35 { 41 36 if(cmp(num,edge[i].num)) 42 37 { 43 38 ans=edge[i].p;            //这里,不要马上返回 44 39 } 45 40 //return edge[i].p; 46 41 } 47 42 return ans; 48 43 } 49 44 int main() 50 45 { 51 46 int flag=0; 52 47 memset(head,-1,sizeof(head)); 53 48 scanf("%d%d",&n,&k); 54 49 for(int i=1;i<=n;i++) 55 50 { 56 51 int x; 57 52 scanf("%d",&x); 58 53 for(int j=1;j<=k;j++) 59 54 { 60 55 num[i][j]=x%2; 61 56 x/=2; 62 57 } 63 58 } 64 59 for(int i=2;i<=n;i++) 65 60 { 66 61 for(int j=1;j<=k;j++) 67 62 num[i][j]+=num[i-1][j]; 68 63 } 69 64 /*for(int i=1;i<=n;i++) 70 65 { 71 66 for(int j=1;j<=k;j++)cout<<num[i][j]; 72 67 cout<<endl; 73 68 }*/ 74 69 int ans=0; 75 70 for(int i=1;i<=n;i++) 76 71 { 77 72 int t=num[i][k]; 78 73 for(int j=1;j<=k;j++) 79 74 { 80 75 num[i][j]-=t; 81 76 //if(num[i][j]<0) num[i][j]=-num[i][j]; 82 77 } 83 78 } 84 79 /*for(int i=1;i<=n;i++) 85 80 { 86 81 87 82 for(int j=1;j<=k;j++) 88 83 cout<<num[i][j]; 89 84 cout<<endl; 90 85 }*/ 91 86 for(int i=1;i<=n;i++) 92 87 { 93 88 int base=0; 94 89 for(int j=1;j<=k;j++) 95 90 { 96 91 base+=num[i][j]; 97 92 base*=10; 98 93 base%=mod; 99 94 //cout<<base<<endl; 100 95 } 101 96 if(base<0) base=-base; 102 97 int tmp=search(num[i],base); 103 98 if(tmp>0) 104 99 { 105100 int t=abs(tmp-i); 106101 if(t>ans) 107102 { 108103 //cout<<tmp<<" "<<i<<endl; 109104 ans=t; 110105 } 111106 } 112107 if(base==0) 113108 { 114109 ans=max(i,ans); 115110 } 116111 ins(num[i],base,i); 117112 } 118113 printf("%d\n",ans); 119114 return 0; 120115 }
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )