poj 3274 Gold Balanced Lineup
这题真的没有想到可以用HASH,对HASH又有了新的理解.
算法:
1.二分枚举,TLE
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<iostream> #include<algorithm> #include<map> #include<math.h> using namespace std; int N, k; struct node { int bit[40]; }tx[101000]; int sum[40]; int jugde(int x ) { for( int i = 1; i <= N; i++) { memset(sum, 0, sizeof(sum)); if( i + x - 1 > N ) break; for( int j = i; j <= i + x - 1 && j <= N; j++) { for( int l = 0; l < k; l++) { sum[l] += tx[j].bit[l]; } } int f = 1; for( int l = 0; l < k - 1; l++) { if( sum[l+1] - sum[l] != 0 ) f = 0; } if( f ) return 1; } return 0; } int search( int l, int r) { int ans = 0; while( l <= r ) { int mid = (l + r) / 2; if( jugde( mid ) ) { ans = mid; l = mid + 1; } else { r = mid - 1; } } return ans; } int main( ) { int ans, n; while( scanf("%d%d", &N, &k) != EOF) { for( int i = 1; i <= N; i++) { scanf("%d",&ans); n = 0; while( ans ) { tx[i].bit[n++] = ans&1; ans = ans >> 1; } } printf("%d\n",search(0, N)); } return 0; }
2.奇妙的HASH,见代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<iostream> #include<algorithm> #include<map> #include<math.h> using namespace std; int sum[100010][40]; int hash[1000010]; int C[100010][40], N, k; /* sum[i][j]表示从第i头cow 到第j头cow属性j的和。 根据题意可知 sum[i][0] - sum[j][0] = sum[i][1] - sum[j][1] = ...= sum[i][k-1] - sum[j][k-1] 求最大的区间(i,j) 问题转化: sum[i][1] - sum[i][0] = sum[j][1] - sum[j][0]; sum[i][2] - sum[i][0] = sum[j][2] - sum[j][0]; ... sum[i][k] - sum[i][0] = sum[j][k] - sum[j][0]; 令C[i][1] = sum[i][1] - sum[i][0]; 求最长区间使得 C[i] == C[j] */ int get_key(int *c) { int p = 0; for( int i = 0; i < k; i++) { p = ((p<<2) + (c[i]>>4))^(c[i]<<10); } p = p % 99983; if( p < 0 ) p = p + 99983; //此处原来写成了p + 99983错的痛苦 return p; } int main( ) { int ans = 0, maxn; memset(sum, 0, sizeof(sum)); memset(C, 0, sizeof(C)); while( scanf("%d%d",&N, &k) != EOF ) { memset(hash, -1, sizeof(hash)); maxn = 0; hash[get_key(C[0])] =0; for( int i = 1; i <= N; i++) { scanf("%d", &ans); for( int j = 0; j < k; j++) { sum[i][j] = sum[i-1][j] + ans % 2; ans = ans>>1; if( ans < 0 ) ans = 0; C[i][j] = sum[i][j] - sum[i][0]; } int p = get_key(C[i]), j; while( hash[p] != -1) { for(j = 1; j < k; j++) { if( C[i][j] != C[hash[p]][j] ) break; } if( j == k ) { if( i - hash[p] > maxn ) maxn = i - hash[p]; break; } p++; } if( hash[p] == -1 ) hash[p] = i; } printf("%d\n",maxn); } return 0; }
posted on 2012-07-18 17:44 more think, more gains 阅读(147) 评论(0) 编辑 收藏 举报