pku 3274 Gold Balanced Lineup 哈希处理
2012-03-27 21:56
127 查看
http://poj.org/problem?id=3274
看到这个题的时候直接给理解错了,以为求存在第k个属性,的牛的个数,直接谢了个排序+二分查找样例过了一交WA了。。心情很郁闷。。自己完全把题意理解错了。
题意是求满足i到j 的差值最大且i到j牛的前k个属性每种属性求和,并且和要相等。求出最大的j - i;
sum[i][j] 表示从第一头牛到第i头牛拥有j属性的牛的个数,则根据题意有,如果i -> j 最大则有
sum[j][0] - sum[i][0] = sum[j][1] - sum[i][1] = sum[j][2] - sum[i][2] = .......... = sum[j][k -1] - sum[i][k - 1];
==> sum[i][1] - s[i][0] = sum[j][1] - sum[j][0];
sum[i][2] - sum[i][0] = sum[j][2] - sum[j][0]
..........
所以有过程:
给出SAMPLE
7 3
7
6
7
2
1
4
2
先转化成二进制:
1 1 1
1 1 0
1 1 1
0 1 0
0 0 1
1 0 0
0 1 0
然后在列上进行累加:
1 1 1
2 2 1<----
3 3 2
3 4 2
3 4 3
4 4 3<----
4 5 3
上面这两步转化还好想。答案是4,是因为两个箭头所指的行列上的差相等。
然后在行上,所有值减去最右边的数:
0 0 0
1 1 0<----
1 1 0
1 2 0
0 1 0
1 1 0<----
1 2 0
然后利用哈希,判断相等且距离最远的。。
View Code
看到这个题的时候直接给理解错了,以为求存在第k个属性,的牛的个数,直接谢了个排序+二分查找样例过了一交WA了。。心情很郁闷。。自己完全把题意理解错了。
题意是求满足i到j 的差值最大且i到j牛的前k个属性每种属性求和,并且和要相等。求出最大的j - i;
sum[i][j] 表示从第一头牛到第i头牛拥有j属性的牛的个数,则根据题意有,如果i -> j 最大则有
sum[j][0] - sum[i][0] = sum[j][1] - sum[i][1] = sum[j][2] - sum[i][2] = .......... = sum[j][k -1] - sum[i][k - 1];
==> sum[i][1] - s[i][0] = sum[j][1] - sum[j][0];
sum[i][2] - sum[i][0] = sum[j][2] - sum[j][0]
..........
所以有过程:
给出SAMPLE
7 3
7
6
7
2
1
4
2
先转化成二进制:
1 1 1
1 1 0
1 1 1
0 1 0
0 0 1
1 0 0
0 1 0
然后在列上进行累加:
1 1 1
2 2 1<----
3 3 2
3 4 2
3 4 3
4 4 3<----
4 5 3
上面这两步转化还好想。答案是4,是因为两个箭头所指的行列上的差相等。
然后在行上,所有值减去最右边的数:
0 0 0
1 1 0<----
1 1 0
1 2 0
0 1 0
1 1 0<----
1 2 0
然后利用哈希,判断相等且距离最远的。。
View Code
#include <cstdio> #include <cstring> #include <iostream> #define maxn 1000007 #define N 32 using namespace std; struct node { int num; node *next; }*hash[maxn + 12],H[maxn]; int n,k,pos; int sum[maxn] ,c[maxn] ; int isok(int x,int y) { int i; for (i = 0; i < k; ++i) { if (c[x][i] != c[y][i]) break; } if (i == k) return y -x; else return -1; } int main() { int i,j,a; int Max = 0; pos = 0; memset(hash,0,sizeof(hash)); node *tt = &H[pos++];//这里是个陷阱,要考虑到hash之后的s可能是0,discuss的数据给的提示 tt->num = 0; tt->next = hash[0]; hash[0] = tt; scanf("%d %d",&n,&k); //初始化 for (i = 0; i <= n; ++i) { for (j = 0; j < N; ++j) { c[i][j] = sum[i][j] = 0; } } for (i = 1; i <= n; ++i) { scanf("%d",&a); for (j = 0; j < k; ++j) { sum[i][j] += sum[i - 1][j]; sum[i][j] += a&1; a = a>>1; } int tmp = sum[i][0]; int s = 0; for (j = 1; j < k; ++j) { c[i][j] = sum[i][j] - tmp; s += c[i][j]; } s %= maxn; if (s < 0) s = -s; node *t; bool flag = false; for (t = hash[s]; t != NULL; t = t->next) { int len = isok(t->num,i); if (len >= 0) { flag = true; Max = max(Max,len); } } if (!flag) { node *q; q = &H[pos++]; q->num = i; q->next = hash[s]; hash[s] = q; } } printf("%d\n",Max); return 0; }
相关文章推荐
- PKU_1002 浮点数N次方的精确计算
- PKU 3468
- pku2704 Pascal's Travels
- pku3678 Katu Puzzle 2-sat判断是否存在可行解
- pku2945 Find the Clones
- pku1655 Balancing Act
- pku2817 WordStack
- 《ACM程序设计》例题解析-PKU3187
- pku 1979 Red and Black---dfs
- PKU-1458 Common Subsequence (最长公共子序列LCS)
- PKU1062+dijkstra
- pku3090 Visible Lattice Points
- ZOJ和PKU 题目分类
- pku 1690 (Your)((Term)((Project))) (模拟题)
- pku 3264 Balanced Lineup ( rmq or 线段树 )
- PKU 1797 Heavy Transportation(Kruscal)
- pku 3126 Prime Path (bfs)
- Knight Moves_pku_1915(广搜).java
- PKU 3159 Candies 差分约束 SPFA
- 期望-pku-oj-1055:Tree