博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 3274 Gold Balanced Lineup(哈希)
阅读量:5221 次
发布时间:2019-06-14

本文共 2542 字,大约阅读时间需要 8 分钟。

题意 :农夫约翰的n(1 <= N <= 100000)头奶牛,有很多相同之处,约翰已经将每一头奶牛的不同之处,归纳成了K种特性,比如1号特性代表它身上有斑点,2号特性代表它比较喜欢用passcal 写程序而不是C 。约翰使用“特性标识符”来描述奶牛的各种特性,例如:一头奶牛的特性标识符是13,将13写成二进制1101,从右向左看,就表示这头奶牛具有1,3,4这三个特性,但没有2号特性,约翰把n头奶牛排成一排,发现在有些连续区间里的奶牛,每种特性出现的次数是一样的,约翰把这样的区间成为平衡的,约翰希望你帮忙找出平衡区间的最大长度 。

思路:虽说知道这个题要用哈希,但是却不知道具体怎么用哈希,我觉得这个题真是有够麻烦的。

数组sum[i][j]表示从第1到第i头cow属性j的出现次数。

所以题目要求等价为: 求满足 sum[i][0]-sum[j][0]=sum[i][1]-sum[j][1]=.....=sum[i][k-1]-sum[j][k-1] (j<i)  中最大的i-j

 将上式变换可得到

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

 

所以只需求满足C[i][]==C[j][] 中最大的i-j,其中0<=j<i<=n。

C[i][]==C[j][] 即二维数组C[][]第i行与第j行对应列的值相等,

那么原题就转化为求C数组中 相等且相隔最远的两行的距离i-j

样例解释:先将十进制转化成二进制(因为题目中转化成的二进制是从左往右读的)

7---->111

6---->011

7---->111

2---->010

1---->100

4---->001

2---->010

将这7行二进制逐行累加得到

111

122

233

243

343

344

354

再利用C[i][y]=sum[i][y]-sum[i][0]求C数组,即所有列都减去第一列(注意C数组有第0行,为全0)

 0 0 0 -->第0行

0 0 0

0 1 1

0 1 1

0 2 1

0 1 0

0 1 1

0 2 1

显然第2行与第6行相等,均为011,且距离最远,距离为6-2=4,这就是所求。

#include 
#include
#include
#include
using namespace std ;const int maxx = 100003 ;const int maxn = 32 ;int sum[maxx][maxn];int head[maxx],next[maxx] ;int K ;int hash(int c[]){ int h = 0 ; for(int i = 0 ; i < K ; i++) h = ((h << 2) + (c[i] >> 4))^(c[i] << 10) ; h = h % maxx ; h = h < 0 ? (h+maxx) : h ; return h ;}int main(){ int N ,f; memset(head ,-1 ,sizeof(head)) ; memset(sum,0,sizeof(sum)) ; int ans = 0 ; scanf("%d %d",&N,&K) ; for(int i = 1 ; i <= N ; i++) { scanf("%d",&f) ; for(int j = 0 ; j < K ; j++) { sum[i][j] = f & 1 ; f = f >> 1 ; } } for(int i = 2 ; i <= N ; i++) { for(int j = 0 ; j < K; j++) sum[i][j] += sum[i-1][j] ; } for(int i = 0 ; i <= N ; i++) { int temp = sum[i][0] ; for(int j = 0 ; j < K; j++) sum[i][j] -= temp ; int h = hash(sum[i]) ; bool flag = 0 ; for(int e = head[h] ; e != -1 ; e = next[e]) { if(memcmp(sum[e],sum[i],sizeof(sum[i])) == 0) { ans = max(ans,i-e ) ; flag = 1 ; break ; } } if(!flag) { next[i] = head[h] ; head[h] = i ; } } printf("%d\n",ans) ; return 0 ;}
View Code

 

转载于:https://www.cnblogs.com/luyingfeng/p/3523564.html

你可能感兴趣的文章
oracle数据链接
查看>>
2018-2019-1 20189215 《Linux内核原理与分析》第七周作业
查看>>
java FTP和SFTP相关操作
查看>>
sql plus 导出建表语句
查看>>
远程管理中的screen-多窗口工具
查看>>
树莓派进阶之路 (001) - 常用镜像高速下载
查看>>
最近项目使用技术
查看>>
C++ 中的权限控制
查看>>
python学习--文件操作实例一
查看>>
[ 转载 ] Java基础13--equals方法
查看>>
springCore 官方文档 中英对照 翻译 5.1.7版(一)
查看>>
PHP闭包和匿名函数
查看>>
JSON 转JAVA代码
查看>>
jquery cache data
查看>>
hdu5723 多校第一题,longlong
查看>>
[转]三维数字地球发布平台探索--几款开源软件介绍
查看>>
[转]地图投影的N种姿势
查看>>
mysql小技巧
查看>>
使用FileReader()预览图片
查看>>
htop详解
查看>>