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()
② 一开始的状态不要忘记了
详见代码吧
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }