hash poj3274

感觉是一道很好的题目~
题意:n头牛站一排,每个牛有k个属性,每个值为1或0。要求找一个牛的最长连续队伍(子段),这个队伍中拥有每个属性的牛的个数相同。
没想到怎么用hash,看的解题报告,觉得转化这里很不错,一转化就柳暗花明了。
不等式或者等式由两个(i,j)之间的关系 转换成 一个之间的关系 (i,i),时间复杂度由O(N^2)变成了近似O(N)。
解题报告:http://blog.csdn.net/lyy289065406/article/details/6647365

有两个细节出错,WA了两次。
① sum和可能是负数,所以要加上fabs()
② 一开始的状态不要忘记了
详见代码吧

View Code
 1 #include <stdio.h>
 2 #include <math.h>
 3 #include <vector>
 4 #include <string.h>
 5 #include <iostream>
 6 using namespace std;
 7 //n<=100,000 k<=30
 8 const int N=100005;
 9 const int K=32;
10 const int prime=1000007;
11 int sum[N][K];
12 int f[N][K];
13 vector<int> hash[prime];
14 int main(){
15     int i,j,l;
16     int n,k,tmp;
17     int res=0;
18     scanf("%d%d",&n,&k);
19     memset(sum,0,sizeof(sum));
20     hash[0].push_back(0);///!!!!!!!
21     for(i=1;i<=n;i++){
22         scanf("%d",&tmp);
23         int tot=0;
24         for(j=0;j<k;j++){
25             sum[i][j]=(tmp&1)+sum[i-1][j];
26             f[i][j]=sum[i][j]-sum[i][0];
27             tmp>>=1;
28             tot+=f[i][j];
29         }
30         tot=fabs(tot);///!!!!!!!
31         tot%=prime;
32         int size=hash[tot].size();
33         for(j=0;j<size;j++){
34             int flag=1;
35             int idx=hash[tot][j];
36             for(l=0;l<k;l++){
37                 if(f[idx][l]!=f[i][l]) {
38                     flag=0;break;
39                 }
40             }
41             if(flag&&(i-idx)>res)
42                 res=i-idx;
43         }
44         hash[tot].push_back(i);
45     }
46     printf("%d\n",res);
47     return 0;
48 }

 

posted @ 2013-05-04 20:51  _sunshine  阅读(192)  评论(0编辑  收藏  举报