POJ - 3274 - Gold Balanced Lineup (hash)

题解:POJ - 3274

题意:

题解:

手推公式:

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矩阵,每个元素减去第一列

这题的hash方法跟POJ-2002很相似,就是当那个hash值被利用时,那么我就让hash++去记录,直到找到没被利用的hash值

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100005
#define mod 1000000 //此处mod定义为99997时,运行时间1000多MS 
using namespace std;
int hash[MAX*10];//hash表储存下标 
int sum[MAX][35];//第 1 头牛到第 i 头的对应属性的和 
int c[MAX][35];//存放每头牛属性 j与第一个属性的差 
int n,k;
int Hash_key(int *cc)
{
	int j,key=0;
	for(j=1;j<k;j++)
		key=key%mod+cc[j]<<2;//此处用 * 乘超时 
	key=abs(key)%mod;//此处得到的key可能会是负数,所以取绝对值 
	return key;
}
int main()
{
	int i,j,x,maxlen=0;//maxlen为最大长度 
	scanf("%d%d",&n,&k);
	memset(hash,-1,sizeof(hash));//初始化哈希表 
	hash[0]=0;//hash表首位初始化 
	for(i=1;i<=n;i++)
	{
		scanf("%d",&x);
		for(j=0;j<k;j++)
		{
			sum[i][j]=sum[i-1][j]+x%2;
			c[i][j]=sum[i][j]-sum[i][0];
			x>>=1;//转化为二进制
		}
		int key=Hash_key(c[i]);
		while(hash[key]!=-1)//处理关键字冲突 
		{
			for(j=0;j<k;j++)//当前牛的属性与其关键字相同的进行比较 
				if( c[i][j]!=c[ hash[key] ][j] )break;
			if(j==k && maxlen<(i-hash[key]))//若j==k,说明两头牛的属性个数相同 
			{
				maxlen=i-hash[key];
				break;
			}
			key++;//往后继续移动处理冲突 
		}
		if(hash[key]==-1)
			hash[key]=i; //将下标存放在hash中 
	}
	printf("%d\n",maxlen);	
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值