您的位置:首页 > 编程语言 > Go语言

Gold Balanced Lineup--POJ 3274

2010-07-21 21:30 302 查看
1、题目类型:哈希表、位运算。

2、解题思路:题意,N个数,它们用K位的二进制表示,寻找最长的区间使其各个进制位上的和都没有发生变化的情况。步骤,(1)将所有N个数转化为K位的二进制形式,并比较与初始位置的差值存储在arr[i]中;(2)Hash编码arr[i],Hash编码公式为:tmp=((tmp<<2)+(v[i]>>4))^(v[i]<<10) ;(3)判断是否存在冲突,存在冲突并且匹配成功时,判断区间大小,直到找到答案。

3、注意事项:注意当Hash编码冲突且匹配不成功时,tmp++,下一位保存;注意取prime的大小要求适当。

4、实现方法:

#include<iostream>
using namespace std;
#define maxn 100010
#define prime 999983

int n,k,ans;
int arr[maxn][31],sum[maxn][31],hash[1000000];

//Hash编码方式
int Encode(int *v,int k)
{
int i,tmp=0;
//Hash公式
for(i=0;i<k;i++)
tmp=((tmp<<2)+(v[i]>>4))^(v[i]<<10);
tmp = tmp%prime;
if(tmp<0)    tmp=tmp+prime;
return tmp;
}

int main()
{
int i,j,num,tmp;
memset(sum,0,sizeof(sum));
memset(hash,-1,sizeof(hash));
memset(arr,0,sizeof(arr));

scanf("%d%d",&n,&k);
hash[Encode(arr[0],k)]=0;

for(i=1;i<=n;i++)
{
scanf("%d",&num);
for(j=0;j<k;j++)
{
arr[i][j]=num%2;
num>>=1;
sum[i][j]=sum[i-1][j]+arr[i][j];
arr[i][j]=sum[i][j]-sum[i][0];
}
tmp=Encode(arr[i],k);
//Hash存在冲突
while(hash[tmp]!=-1)
{
//验证arr[i]是否相同
for(j=1;j<k;j++)
{
if(arr[i][j]!=arr[hash[tmp]][j])
break;
}
if(j==k)
{
if(i-hash[tmp]>ans)
ans=i-hash[tmp];
break;
}
tmp++;
}
//Hash不存在冲突
if(hash[tmp]==-1)
hash[tmp]=i;
}
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: