Gold Balanced Lineup
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 10360   Accepted: 3086

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

题目大意就是说n个数,表示n头牛所具有的特性,在化为二进制之后哪一位是1表示具有哪种特性,问最长连续有多少个牛,它们所有每一种特性的和相等,如:7->1 1 16->1 1 07->1 1 12->0 1 01->0 0 14->1 0 02->0 1 0这样的话从第3行到第6行共4行的长度,它们3种特性的和都为2

大概意思就是:

数组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] = sum[j][k-1]-sum[j][0]

令C[i][y]=sum[i][y]-sum[i][0] (0<y<k)

初始条件C[0][0~k-1]=0

所以只需求满足C[i][]==C[j][] 中最大的i-j,其中0<=j<i<=n。

C[i][]==C[j][] 即二维数组C[][]第i行与第j行对应列的值相等,

那么原题就转化为求C数组中 相等且相隔最远的两行的距离i-j

这样的话就只需要对数组c进行哈希,下面是网上借鉴来的哈希函数

 inline int hashcode(const int *v){int s = 0;for(int i=0; i<k; i++)s=((s<<2)+(v[i]>>4))^(v[i]<<10);s = s % M;s = s < 0 ? s + M : s;return s;}

另外,在寻找最长满足条件区间长度的时候,我用了一个数组min_index来存放两行相同时上面一行的下标。最初min_index[i]=i.之后一旦找到一个c[j]=c[i],那么min_index[j]=min_index[i].这样的话最大的i-min_index[i]就是最常去肩长度。当然,还有更多较好的方法,如用结构体放最长长度,一边插入就可以一边找到最大长度。下面附上代码:
  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<math.h>
  4 #define mem(a) memset(a,0,sizeof(a))
  5 #define MAX 100005
  6 #define maxn 107777
  7
  8 int hash[maxn+5],next[MAX],c[MAX][32],min_index[MAX];
  9 int n,k;
 10
 11 int abss(int a)//坑爹的code block,不能直接调用abs
 12 {
 13     return a>=0?a:-a;
 14 }
 15
 16 bool judge(int a,int b)//判断两行是否相同
 17 {
 18     int i;
 19     for(i=0;i<k;i++)
 20     {
 21         if(c[a][i]!=c[b][i])return false;
 22     }
 23     return true;
 24 }
 25
 26 inline int hashcode(const int *v)//哈希函数
 27 {
 28     int s = 0;
 29      for(int i=0; i<k; i++)
 30          s=((s<<2)+(v[i]>>4))^(v[i]<<10);
 31      s = s % maxn;
 32      s = s < 0 ? s + maxn : s;
 33      return s;
 34 }
 35
 36 bool all_0(int index)//判断这一行是不是全部为0,
 37                     //是的话那么它与他之前的所有行组合起来可以满足条件
 38 {
 39     int i;
 40     for(i=0;i<k;i++)
 41     {
 42         if(c[index][i]!=0)return false;
 43     }
 44     return true;
 45 }
 46
 47 void insert(int index)//插入第index行的c[index]
 48 {
 49     int h=hashcode(c[index]);
 50     if(!h)//这一行里面全是 0
 51     {
 52         if(all_0(index)){
 53             min_index[index]=0;
 54             return ;
 55         }
 56     }
 57     int u=hash[h];
 58     if(!u)
 59     {
 60         min_index[index]=index;
 61         hash[h]=index;
 62         return;
 63     }
 64     while(u)
 65     {
 66         if(judge(index,u))//如果找到一行与这行相同,就把这条链最小下标传过去
 67         {
 68             min_index[index]=min_index[u];
 69             return;
 70         }
 71         u=next[u];
 72     }
 73     min_index[index]=index;
 74     next[index]=hash[h];
 75     hash[h]=index;
 76 }
 77
 78 int main()
 79 {
 80  //   freopen("in.txt","r",stdin);
 81  //   freopen("out1.txt","w",stdout);
 82     while(~scanf("%d%d",&n,&k))
 83     {
 84         mem(hash);
 85         mem(next);
 86         mem(min_index);
 87         mem(c);
 88
 89         int sum[32]={0},i,j,num;
 90         for(i=1;i<=n;i++)
 91         {
 92             scanf("%d",&num);
 93             for(j=0;j<k;j++)
 94             {
 95                 sum[j]+=( ( (1<<j)&(num) )?1:0 );
 96                 c[i][j]=sum[j]-sum[0];
 97             }
 98             insert(i);
 99         }
100         int max=0;
101         for(i=1;i<=n;i++)
102         {
103             max=max>(i-min_index[i])?max:(i-min_index[i]);
104         }
105         printf("%d\n",max);
106     }
107     return 0;
108 }

转载于:https://www.cnblogs.com/gj-Acit/archive/2013/05/20/3089047.html

POJ3274Gold Balanced Lineup(哈希)相关推荐

  1. POJ 3274 Gold Balanced Lineup(哈希)

    题目链接 很难想.会哈希,但是想不出.需要一个转化,本来是求某一段上的二进制上每一位的1数目相等,转化为找两段相等的,换元可推出公式.最后注意特判.. 1 #include <iostream& ...

  2. poj3264 - Balanced Lineup(RMQ_ST)

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 45243   Accepted: 21240 ...

  3. POJ 3264 Balanced Lineup

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 53629   Accepted: 25223 ...

  4. poj 3264 Balanced Lineup RMQ问题 线段树

    For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One d ...

  5. [BZOJ] 1637: [Usaco2007 Mar]Balanced Lineup

    1637: [Usaco2007 Mar]Balanced Lineup Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 697  Solved: 463 ...

  6. POJ 3264 Balanced Lineup【线段树区间查询求最大值和最小值】

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 53703   Accepted: 25237 ...

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

    1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 510   ...

  8. POJ 3264 Balanced Lineup(RMQ)

    Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 24349   Accepted: 11348 ...

  9. 专题突破一之分块——Untitled Problem II,Balanced Lineup,[ioi2009]Regions

    文章目录 SP2940 UNTITLE1 - Untitled Problem II source solution code Balanced Lineup source code Count on ...

最新文章

  1. 2016030204 - git和github结合
  2. 2021年春季学期-信号与系统-第十三次作业参考答案-第一小题
  3. 好久没写了,重装了系统重新配置的Live Writer,看看效果:
  4. 国内数据中心制冷系统设计与发展
  5. createBindingContext in SAP UI5
  6. solidity bytes 智能合约开发知识浅学(五点一)bytes基本概念
  7. 前端学习(1647):前端系列实战课程之选项卡实现js思路
  8. 机器学习之 朴素贝叶斯、贝叶斯网络
  9. Qt:Qt实现飞秋拦截助手—ARP攻击
  10. C# 托管资源与非托管资源
  11. 解决 Flex模块切换后导致对象转换失败 注册信息丢失
  12. insertAfter函数
  13. 关于2020新版idea,maven工程依赖成功导入、但运行找不到jar包问题解决。
  14. baum welch java_Baum Welch估计HMM参数实例
  15. 基本类型,指针,双指针作为函数参数
  16. 【Magick++透明图层合并】
  17. 短信API接口怎么调用?
  18. 你真正了解图像金字塔吗?详细介绍拉普拉斯金字塔和高斯金字塔(pyrDown() and pyrUp()),参考《OpenCV轻松入门:面向Python》
  19. 在微型计算机中 集成在微处理,在微型计算机中,微处理器的主要功能是进行什么...
  20. 字符串统计(2017)

热门文章

  1. C++:17---函数指针
  2. C++(6)--初识循环while,do-while
  3. FFmepg 多线程解码历程
  4. H.265:网络视频的高清时代
  5. 轻松理解—继承成员访问控制机制
  6. H.264将普及 视频编码讲坛之H.264前世今生
  7. VisualCode 查看代码历史版本、还原代码到既定历史版本
  8. webpack 入门,说一下那些不入流的知识点、module.exports{ } 中配置说明
  9. mysql 数据库函数入门
  10. windows下安装和设置gradle