哈希-Gold Balanced Lineup 分类: POJ 哈希 2015-08-07 09:04 2人阅读 评论(0) 收藏

Gold Balanced Lineup
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 13215 Accepted: 3873

Description

Farmer John’s N cows (1 ≤ N ≤ 100,000) share many similarities. In fact, FJ has been able to narrow down the list of features shared by his cows to a list of only K different features (1 ≤ K ≤ 30). For example, cows exhibiting feature #1 might have spots, cows exhibiting feature #2 might prefer C to Pascal, and so on.

FJ has even devised a concise way to describe each cow in terms of its “feature ID”, a single K-bit integer whose binary representation tells us the set of features exhibited by the cow. As an example, suppose a cow has feature ID = 13. Since 13 written in binary is 1101, this means our cow exhibits features 1, 3, and 4 (reading right to left), but not feature 2. More generally, we find a 1 in the 2^(i-1) place if a cow exhibits feature i.

Always the sensitive fellow, FJ lined up cows 1..N in a long row and noticed that certain ranges of cows are somewhat “balanced” in terms of the features the exhibit. A contiguous range of cows i..j is balanced if each of the K possible features is exhibited by the same number of cows in the range. FJ is curious as to the size of the largest balanced range of cows. See if you can determine it.

Input
Line 1: Two space-separated integers, N and K.
Lines 2..N+1: Line i+1 contains a single K-bit integer specifying the features present in cow i. The least-significant bit of this integer is 1 if the cow exhibits feature #1, and the most-significant bit is 1 if the cow exhibits feature #K.

Output
Line 1: A single integer giving the size of the largest contiguous balanced group of cows.

Sample Input

7 3
7
6
7
2
1
4
2

Sample Output

4

Hint
In the range from cow #3 to cow #6 (of size 4), each feature appears in exactly 2 cows in this range

Source
USACO 2007 March Gold
题意:有n头牛,每头牛都有不同的属性,这些属性可以通过数字转化的二进制表示,问最大的连续的区间长度使的这个区间的牛的各种属性的和相等.
就是保持平衡
方法:假设有一个数组sum[][]记录了第1头牛到第i头牛各种属性的和,在区间[j,i],判断是不是平衡就是判断sum[i][0]-sum[j][0]=sum[i][1]-sum[j][1]……=sum[i][k]-sum[j][k];
转化一下就是判断
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][3]-sum[i][0]=sum[j][3]=sum[j][0],
.
.
.
sum[i][k]-sum[i][0]=sum[j][k]=sum[j][0];
所以我们只需要记录cmp[i][j]=sum[i][j]-sum[i][0];
如果cmp[i][]=cmp[j][],则说明[j,i]区间是平衡的,记录i-j的最大值.

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define eps 1e-9
#define LL long long
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define CRR fclose(stdin)
#define CWW fclose(stdout)
#define RR freopen("input.txt","r",stdin)
#define WW freopen("output.txt","w",stdout)

const int MAX = 100010;

const int Mod = 1001007;

int Hash[Mod+100];

int sum[MAX][40],cmp[MAX][40];
int n,k;
int has(int *s)//哈希值转化,题解看的,不明白
{
    int p=0;
    for(int i=0; i<k; i++)
    {
        p = ((p<<2)+(s[i]>>4))^(s[i]<<10);
    }
    p%=Mod;
    if(p<0)
    {
        p+=Mod;
    }
    return p;
}

int main()
{

    int data;
    int Max = 0;
    scanf("%d %d",&n,&k);
    memset(Hash,-1,sizeof(Hash));
    Hash[has(cmp[0])]=0;
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&data);
        for(int j=0; j<k; j++)
        {
            sum[i][j]=data&1;
            data=data>>1;
            sum[i][j]+=sum[i-1][j];
            cmp[i][j]=sum[i][j]-sum[i][0];
        }
        int ans = has(cmp[i]);
        while(Hash[ans]!=-1)
        {
            int R;
            for(R=0; R<k; R++)
            {
                if(cmp[i][R]!=cmp[Hash[ans]][R])
                {
                    break;
                }
            }
            if(R==k)
            {
                if(Max<i-Hash[ans])
                {
                    Max=i-Hash[ans];
                    break;
                }
            }
            ans++;
        }
        if(Hash[ans]==-1)
        {
            Hash[ans]=i;
        }
    }
    printf("%d\n",Max);
    return  0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2015-08-07 09:04  一骑绝尘去  阅读(135)  评论(0编辑  收藏  举报