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] = ‘\0‘;
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\n",max);
85     return 0;
86 }

  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] = ‘\0‘;
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\n",max);
97     return 0;
98 }

poj 3274 -- Gold Balanced Lineup

时间: 2024-10-11 20:39:06

poj 3274 -- Gold Balanced Lineup的相关文章

poj 3274 Gold Balanced Lineup, 拉链式hash

sum[i][j] 表示从第1到第i头cow属性j的出现次数 所以题目要求等价为: 求满足 sum[i][0]-sum[j][0]=sum[i][1]-sum[j][1]=.....=sum[i][k-1]-sum[j][k-1] (j<i) 中最大的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-1]-sum[i][0

POJ 3474 Gold Balanced Lineup Hash

题意一开始不是很明确, 后来发现是每一种特征出现的次数相同 这样一来就变成简单hash问题了,如果把每个特征看看做是一个(n+1)进制数的话,对奶牛序列求一下前缀和,如果i - j这一段每一种特征出现的次数相同的话,把i - 1点和j点的每一位减去所有位中的最小值之后,必然相等,所以hash判断一下就好. #include <cstdio> #include <cstring> #include <iostream> #include <map> #incl

bzoj1702[Usaco2007 Mar]Gold Balanced Lineup 平衡的队列*

bzoj1702[Usaco2007 Mar]Gold Balanced Lineup 平衡的队列 题意: N头牛,一共K种特色.每头牛有多种特色.[i,j]段被称为balanced当且仅当K种特色在[i,j]内拥有次数相同.求最大的[i,j]段长度.n≤100000,k≤30. 题解: 得到式子:a[i][l]-a[j][l]=a[i][l-1]-a[j][l-1],l在2..k之间,移项得a[i][l]-a[i][l-1]=a[j][l]-a[j][l-1],l在2..k之间,故可以定义一个

1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列

1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 510  Solved: 196[Submit][Status][Discuss] Description Farmer John's N cows (1 <= N <= 100,000) share many similarities. In fact, FJ has been able to narrow

【POJ】3264 Balanced Lineup ——线段树 区间最值

Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 34140   Accepted: 16044 Case Time Limit: 2000MS Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer Joh

poj3274(Gold Balanced Lineup)

题目地址:Gold Balanced Lineup 题目大意: 一个农场有N个奶牛,每个奶牛都有不同的特征,聪明的农夫给奶牛 feature ID.代表奶牛所具有的特征.将feature ID 写成为K位的二进制的数,其中有1的位置代表奶牛具有此特征,0代表没有此特征.从i->j 使这个区间的奶牛所有特征的个数是相等的.其中最大的区间差就是题图所求的. 解题思路: 解题思路: 经典题,不转化问题很难做,先根据官方的方法转化问题,把“求最远的两行间各个特征出现次数相等”转化为“求最远的相同两行”,

POJ 3264:Balanced Lineup Rmq模板

Balanced Lineup 题目链接: http://poj.org/problem?id=3264 题意: 求区间最大值和最小值的差 题解: Rmq模板题 代码 #include<stdio.h> #include<math.h> const int N=5e4+1; int dpmax[N][17]; int dpmin[N][17]; int mmax(int x,int y) { return x>y?x:y; } int mmin(int x,int y) {

POJ 题目3264 Balanced Lineup(RMQ)

Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 39046   Accepted: 18291 Case Time Limit: 2000MS Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer Joh

【POJ 3274】Gold Balanced Lineup (stl map )设计hash表,处理碰撞

题目链接 题目链接 http://poj.org/problem?id=3274 题意 输入每头牛的特征的10进制,若i~j头牛中每个数位的特征相等则满足要求,求所有满足要求的j-i的最大值. 解题思路 抽屉原理,用前缀和处理每个数位即可. 直接暴力的话复杂度太大了,所以需要取巧的办法. 直接暴力求解是sum[i][p] - sum[j][p] == sum[i][0] - sum[j][0].其中i表示第i头牛,j表示第j头牛,p表示第p个特征,i > j. 取巧的办法:sum[i][p] -