poj 3274 Gold Balanced Lineup

这题真的没有想到可以用HASH,对HASH又有了新的理解.

算法:

1.二分枚举,TLE

View Code
#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,见代码

View Code
#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编辑  收藏  举报

导航