POJ 3274 - 数组 + 哈希
来源:互联网 发布:网络假新闻案例 编辑:程序博客网 时间:2024/06/14 02:42
1.Question:
2.Solution:
首先我们通过范例来了解一下题意是什么:
7 31 1 11 1 00 1 00 0 11 0 00 1 0如代码所示,我们k代表的是二进制的位数,n代表的是奶牛个数
注意这种排列是题目要求的唯一的,我们不能改动
最后,我们开始转化问题
首先,我们想要快速的求出差值最好的方法就是就是对数组从头到尾进行累加(这种方法也是非常的优秀)但是本题只用这一种思想是远远不够的
我们想要求最长的满足要求的区间长度的话,还需要对问题进行转化
因为如果我们用朴素的方法的话需要至少O(n^2)的比较次数,这在数据量是10w的时候是无法容忍的,所以我们想要才去跟家高效的查找方式就是哈希
但是我们怎么哈希呢
首先,我们对题意进行转化
sum[i][j]存储第i行的之前的累计的值
carray[i][j]存储每一行的sum[i][j]-sum[i][0]
sum[i][1]-sum[i][0] = sum[j][1]-sum[j][0]
sum[i][2]-sum[i][0] = sum[j][2]-sum[j][0]
......
sum[i][k-1]-sum[i][0] = sum[j][k-1]-sum[j][0]
令C[i][y]=sum[i][y]-sum[i][0] (0<y<k)
初始条件C[0][0~k-1]=0
这里我们就将查找的条件转化成看carray数组的对应位是否相同了(其实不做最后一步转化也可以只不过我们要计算罢了)
最后我们用哈希来高效存储提高查找效率,不断更新我们的最大值就好了
在这里我们总结哈希的本质就是
原本我们需要对每个元素都要重新遍历一遍数组找最大值,但是我们现在通过哈希省去了很大一部分的不必要的判断,我们先明确必要条件然后我们去查询减少了我们的判断的次数
提高时间效率
PS:这里要小心最重要的一点,carray数组的第一个元素是从0开始的,不是从1开始的,不然对于
4 41248这种是会出错的,我就是WA在这里了
3.Code:
#include"iostream"#include"cstdio"#include"cstring"#include"cmath"#include"cstdlib"#define N 1000000 //100w的散列 #define MAX 100005 //10w的数据量 using namespace std;typedef struct node{int x;struct node* next;}point;int n,k;int sum[MAX][32];int carray[MAX][32];point hash[N]; //散列记录下标 int hash_function(int i){int p=0;for(int j=0;j<k;j++){p=((p+(carray[i][j])<<2))%N;}return abs(p)%N;}void init(){for(int i=0;i<N;i++) hash[i].next=NULL;point* w=new point; //这里就是WA的核心 w->next=hash[0].next;hash[0].next=w;w->x=0;}int main(){init();int result=0;int x;scanf("%d%d",&n,&k);for(int i=1;i<=n;i++){scanf("%d",&x);for(int j=0;j<k;j++) //问题转化 {sum[i][j]=sum[i-1][j]+(x & 1);carray[i][j]=sum[i][j]-sum[i][0]; x=x>>1; //x是正数 } int key=hash_function(i); //将carray的第i行哈希,返回散列地址 point* w=hash[key].next;while(w!=NULL){int j;for(j=0;j<k;j++){if(carray[i][j]!=carray[w->x][j]) break;}if(j==k&&result<i-w->x) result=i-w->x; w=w->next;} point* h=new point;h->x=i;h->next=hash[key].next;hash[key].next=h;}printf("%d\n",result);return 0;}
0 0
- POJ 3274 - 数组 + 哈希
- POJ 3274 Gold Balanced Lineup 数组Hash
- poj 1743 后缀数组
- POJ 2758 后缀数组
- POJ 2774 后缀数组
- POJ 2352 树状数组
- Poj 树状数组
- poj 2774 //后缀数组
- poj 1990【树状数组】
- poj 2352 树状数组
- poj 2481 树状数组
- poj 3067 树状数组
- POJ 2481 树状数组
- POJ 3067 树状数组
- POJ 2352 树状数组
- poj 3294 后缀数组
- poj 2352(树状数组)
- POJ 2481 树状数组
- 关于Web Office控件实现Excel宏文件问题
- linux内核符号表
- linux服务器历险之linux性能监控
- CSS3 基础(006_过渡)
- redis-JedisPoolConfig配置
- POJ 3274 - 数组 + 哈希
- Solr5创建Collection的多core。
- 数字签名与数字证书
- SetWindowPos讲解
- Java之IO概述
- mysql datetime vs timestamp
- Struts的优点/缺点
- 十年·杭研大咖说 | 邱似峰:从应届生到网易视频云CTO的蜕变
- 第11章 结构化数据