zoukankan      html  css  js  c++  java
  • poj 3274 -- Gold Balanced Lineup

    Gold Balanced Lineup
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 12110   Accepted: 3553

    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
     
    题意:农夫john有n头小母牛,每头牛都有一些特点。假设有k个特点。并且用k位二进制表示,如果该位是1说明有此特点,
    否则视为没有。求最长的范围L,满足在这L头牛中,它们的特点数量相等。用数据说明:
    第几头  7 3                1 2 3(第几个特点)
     1    7  ——>  1 1 1
     2    6  ——>  1 1 0
     3    7  ——>  1 1 1  
     4    2  ——>  0 1 0
     5    1  ——>  0 0 1
     6    4  ——>  1 0 0
     7    2  ——>  0 1 0
      可以看到从第3头到第6头牛每个特点的数量和均为2 ,而3-6是最远的范围。可以得出ans is four
     
    思路:
      题意已经明白了,怎么做呢,
        1.将特点累加      
            第几头  7 3                1 2 3(第几个特点)
             1    7  ——>  1 1 1
             2    6  ——>  2 2 1
             3    7  ——>  3 3 2  
             4    2  ——>  3 4 2
             5    1  ——>  3 4 3
             6    4  ——>  4 4 3
             7    2  ——>  4 5 3
        2.减去第1列或者其他列,相同即可。
            第几头  7 3                1 2 3(第几个特点)
             0    0  ——>  0 0 0
             1    7  ——>  0 0 0
             2    6  ——>  1 1 0
             3    7  ——>  1 1 0  
             4    2  ——>  1 2 0
             5    1  ——>  0 1 0
             6    4  ——>  1 1 0
             7    2  ——>  1 2 0
        3.可以看出第2头到第6头都是1 1 0,所以6 - 2 = 4 is answer。 为什么这样呢?
          因为第6头是累加的结果,即:s1+s2+s3+s4+s5+s6. 第2头:s1+s2   所以6-2 就剩下s3+s4+s5+s6。正是我们求的结果。
          这也是为什么要加第0头的原因。如果读者不明白,可以看以下数据:
                    1 2
                    3
                    ans : 1
        4.已经处理的差不多了,剩下的工作就是要离散(hash)查找了。我用的是linux 系统里的ElfHash方法。
     
     
      code1:用vector模拟拉链法。跑了700ms左右
      
     1 /*======================================================================
     2  *           Author :   kevin
     3  *         Filename :   GlodBalancedLineup.cpp
     4  *       Creat time :   2014-07-24 11:39
     5  *      Description :
     6  ========================================================================*/
     7 #include <iostream>
     8 #include <algorithm>
     9 #include <cstdio>
    10 #include <cstring>
    11 #include <queue>
    12 #include <cmath>
    13 #define clr(a,b) memset(a,b,sizeof(a))
    14 #define M 100005
    15 #define MM 18979
    16 using namespace std;
    17 vector<int>hash[M];
    18 int s[M][35],n,k;
    19 int ElfHash(char *name)  //linux hash
    20 {
    21     int h = 0,g;
    22     while(*name){
    23         h = (h<<4) + *name++;
    24         g = h & 0xf0000000;
    25         if(g) h ^= g>>24;
    26         h &= ~g;
    27     }
    28     return (h%MM);
    29 }
    30 int slove(int ch[])   //转换成字符串并求hash值
    31 {
    32     char str[35];
    33     for(int i = 0; i < k; i++){
    34         str[i] = 'F'+ch[i];
    35     }
    36     str[k] = '';
    37     int key = ElfHash(str);
    38     return key;
    39 }
    40 bool judge(int l,int h)   //判断相等
    41 {
    42     for(int i = 0; i < k; i++){
    43         if(s[l][i] != s[h][i]){
    44             return false;
    45         }
    46     }
    47     return true;
    48 }
    49 int Search(int key,int l)  //查找
    50 {
    51     int len = hash[key].size(),max = 0,temp;
    52     for(int i = 0; i < len; i++){
    53         if(judge(l,hash[key][i])){
    54             temp = fabs(l-hash[key][i]);
    55             if(temp > max) max = temp;
    56         }
    57     }
    58     hash[key].push_back(l); //向vector里追加元素
    59     return max;
    60 }
    61 int main(int argc,char *argv[])
    62 {
    63     scanf("%d%d",&n,&k);
    64     int a = 0,max = 0;
    65     clr(s,0);
    66     for(int i = 1; i <= n; i++){
    67         scanf("%d",&a);
    68         for(int j = 0; j < k; j++){
    69             int t = a&1;
    70             if(t) s[i][j] = s[i-1][j]+1;
    71             else  s[i][j] = s[i-1][j];
    72             a = a>>1;
    73         }
    74     }
    75     for(int i = 0; i <= n; i++){
    76         int q = s[i][0];
    77         for(int j = 0; j < k; j++){
    78             s[i][j] -= q;
    79         }
    80         int key = slove(s[i]);
    81         int temp = Search(key,i);
    82         if(temp > max) max = temp;
    83     }
    84     printf("%d
    ",max);
    85     return 0;
    86 }
    View Code

      code2:用静态邻接表模拟拉链。跑了300ms左右

     1 /*======================================================================
     2  *           Author :   kevin
     3  *         Filename :   GlodBalancedLineup.cpp
     4  *       Creat time :   2014-07-24 11:39
     5  *      Description :
     6  ========================================================================*/
     7 #include <iostream>
     8 #include <algorithm>
     9 #include <cstdio>
    10 #include <cstring>
    11 #include <queue>
    12 #include <cmath>
    13 #define clr(a,b) memset(a,b,sizeof(a))
    14 #define M 100005
    15 #define MM 18979
    16 using namespace std;
    17 struct EdgeNode
    18 {
    19     int to,next;
    20 };
    21 EdgeNode Edges[M];
    22 int s[M][35],n,k,head[M],cnt;
    23 void AddEdges(int i,int j,int cnt)
    24 {
    25     Edges[cnt].to = j;
    26     Edges[cnt].next = head[i];
    27     head[i] = cnt;
    28 }
    29 int ElfHash(char *name)
    30 {
    31     int h = 0,g;
    32     while(*name){
    33         h = (h<<4) + *name++;
    34         g = h & 0xf0000000;
    35         if(g) h ^= g>>24;
    36         h &= ~g;
    37     }
    38     return (h%MM);
    39 }
    40 int slove(int ch[])
    41 {
    42     char str[35];
    43     for(int i = 0; i < k; i++){
    44         str[i] = 'F'+ch[i];
    45     }
    46     str[k] = '';
    47     int key = ElfHash(str);
    48     return key;
    49 }
    50 bool judge(int l,int h)
    51 {
    52     for(int i = 0; i < k; i++){
    53         if(s[l][i] != s[h][i]){
    54             return false;
    55         }
    56     }
    57     return true;
    58 }
    59 int Search(int key,int l)
    60 {
    61     int Max = 0,temp;
    62     for(int k = head[key]; k != -1; k = Edges[k].next){
    63         if(judge(l,Edges[k].to)){
    64             temp = fabs(l-Edges[k].to);
    65             if(temp > Max) Max = temp;
    66         }
    67     }
    68     AddEdges(key,l,cnt++);
    69     return Max;
    70 }
    71 int main(int argc,char *argv[])
    72 {
    73     scanf("%d%d",&n,&k);
    74     int a = 0,max = 0;
    75     clr(s,0);
    76     clr(head,-1);
    77     cnt = 0;
    78     for(int i = 1; i <= n; i++){
    79         scanf("%d",&a);
    80         for(int j = 0; j < k; j++){
    81             int t = a&1;
    82             if(t) s[i][j] = s[i-1][j]+1;
    83             else  s[i][j] = s[i-1][j];
    84             a = a>>1;
    85         }
    86     }
    87     for(int i = 0; i <= n; i++){
    88         int q = s[i][0];
    89         for(int j = 0; j < k; j++){
    90             s[i][j] -= q;
    91         }
    92         int key = slove(s[i]);
    93         int temp = Search(key,i);
    94         if(temp > max) max = temp;
    95     }
    96     printf("%d
    ",max);
    97     return 0;
    98 }
    View Code
  • 相关阅读:
    Linux系统运维之MYSQL数据库集群部署(主从复制)
    Linux系统运维之负载均衡Tengine
    Linux系统运维之subversionEdge部署
    Linux系统运维之Hadoop、Hive、Flume数据处理
    CoIDE在STM32系列单片机中的使用实践
    软硬件调试九法:第三条规则 不要想而要看
    《产品经理》读书笔记
    <读书笔记> 代码整洁之道
    关于鼠标手的症状和恢复方法
    <读书笔记>软件调试之道 :从大局看调试-理想的调试环境
  • 原文地址:https://www.cnblogs.com/ubuntu-kevin/p/3865921.html
Copyright © 2011-2022 走看看