poj 3274 Gold Balanced Lineup (神奇的哈希)

题意理解有误狠狠的把自己骗了,每个牛有K个属性,我理解成选出K中属性的,由于思维定势看看题报告

没有发现这个问题。纠结,这几天总犯这种错误。。。

Farmer John's有n头cow,共k个属性,每个属性用一位2进制表示。求最长连续的

段,满足段里的每个属性出现的次数一样多。

sum[][]记录从上之下的和,c[][]记录sum[][]从左到右的差值,

把每个牛的各个属性用哈希处理即可,从上向下贪心即可。

哈希数值 prime  = 99983, 跑了  875MS ,prime =1000000,只跑了250MS 。

至于110000 直接 TLE

#include <stdio.h>
#include <string.h>
const int N=100005;
const int prime=1000000;
int n,k,hash[N*10];
int sum[N][50],c[N][50];

int hashcode(int *v,int k)
{
int p=0;
for(int i=0;i<k;i++)
{
p=((p<<2)+(v[i]>>4))^(v[i]<<10);
}
p%=prime;
if(p<0) p+=prime;
return p;
}
int main()
{
scanf("%d%d",&n,&k);
int ans=0;
memset(hash,-1,sizeof(hash));
hash[hashcode(c[0],k)]=0;
for(int i=1;i<=n;i++)
{
int x;scanf("%d",&x);
for(int j=0;j<k;j++)
{
int t=x%2;x>>=1;
sum[i][j]=sum[i-1][j]+t;
c[i][j]=sum[i][j]-sum[i][0];
}
int p=hashcode(c[i],k),j;
while(hash[p]!=-1)
{
for(j=0;j<k;j++)
{
if(c[i][j]!=c[hash[p]][j])
break;
}
if(j==k&&ans<i-hash[p])
{
ans=i-hash[p];break;
}
p++;
}
if(hash[p]==-1)
hash[p]=i;
}
printf("%d\n",ans);
return 0;
}



你可能感兴趣的:(poj)