• 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
  • 相关阅读:
    别用言语考验底线
    QQ登陆接口
    cookie设置今日不提醒功能
    Sublime Text 3常用插件
    浏览器的标准模式与怪异模式的设置与区分方法
    JS中offsetTop、clientTop、scrollTop、offsetTop各属性介绍
    javascript中闭包的工作原理
    javascript判断图片是否加载完成方法整理
    社会十二效应法则
    小故事
  • 原文地址:https://www.cnblogs.com/ubuntu-kevin/p/3865921.html
Copyright © 2020-2023  润新知