zoukankan      html  css  js  c++  java
  • 哈希-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
    ",Max);
        return  0;
    }
    

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

  • 相关阅读:
    【华为云技术分享】华为云HiLens全面升级,端云协同多模态AI应用开发利器
    【华为云技术分享】MongoDB经典故障系列四:调整oplog大小,引起从库宕机怎么办?
    使用体验神似VS Code?三步带你了解华为云CloudIDE前世今生
    nginx 下配置禅道
    如何在HTTPS 网页中引入HTTP资源: Mixed Content?
    stocket和webstocket的区别
    [转载]input[type=file]在移动端各浏览器无法适配打开相机的问题。
    视频和图片的存储(阿里云OSS还是七牛?)
    VUE 和AngularJS 开发SPA能支持APP内嵌么
    【PHP7.1】使用OpenSSL来代替Mcrypt加解密【原创】
  • 原文地址:https://www.cnblogs.com/juechen/p/4721921.html
Copyright © 2011-2022 走看看