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

PKU-3274-Gold Balanced Lineup

2011-12-07 23:49 351 查看
重在理解题意,想了好久才弄明白题意,大意是有n头牛,有k种特征,要求在这n头牛中,找出连续的第i头和第j头中,满足这些牛的k种特征个数是一样的。

明白了这层意思,似乎仍不知从何下手,看了discuss里,豁然开朗,佩服牛人能想到这。

注:大概思路如下:

111      111      000
110      221<=    110
111      332      110
010      342      120
001      342      120
100      443<=    110
010      453      120

中间一列的221和443的”形状”一样, 也就是相减能得到答案, 所以稍作处理都减去最右边的数即可, 方便比较.

由于N的个数比较大,所以考虑用哈希来查找。code如下:

#include<stdio.h>
#include<stdlib.h>
#define N 100001
#define M 32

int n, k;
int aCase
[M];
int head
;
int hash(int a[])
{
int p, i;
for (i = 0; i < k; i++)
p = ((p << 2) + (a[i] >> 4)) ^ (a[i] << 10);
p %= 99983;
if (p < 0)
p += 99983;
return p;
}

int main(void)
{
scanf("%d%d", &n, &k);
int i, j;
memset(head, -1, sizeof(head));
memset(aCase[0], 0, sizeof(aCase[0]));
int tmp, result = 0;
int h = hash(aCase[0]);
head[h] = 0;

for (i = 1; i <= n; i++){
scanf("%d", &tmp);
for (j = 0; j < k; j++){
aCase[i][j] = aCase[i - 1][j];
aCase[i][j] += tmp & 1;
tmp = tmp >> 1;
}
tmp = aCase[i][0];
for (j = 0; j < k; j++)
aCase[i][j] -= tmp;
h = hash(aCase[i]);
for (; ; h++){
if (head[h] == -1)
break;
int flag = 1;//find the same hash
for (j = 0; j < k; j++){
if (aCase[i][j] != aCase[head[h]][j]){
flag = 0;
break;
}
}
if (flag == 1)
break;//find the same value
}
if (head[h] == -1)
head[h] = i;
else
result = result > (i - head[h]) ? result : (i - head[h]);
}
printf("%d\n", result);
return 0;
}


注:head数组的作用是存放相同元素中第一个元素所计算出的哈希值,以后若找到相同的元素,直接根据

result = result > (i - head[h]) ? result : (i - head[h]);求出最大值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: