POJ 3274 Gold Balanced Lineup

Gold Balanced Lineup
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 5164 Accepted: 1631

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 theK 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

 

 

这道题目的确出的很好

首先是题意的转换,怎么去寻找最大的距离

那么我们看例子

7 3
7
6
7
2
1
4
2

转化为2进制

111

110

111

010

001

100

010

逐个累加

111

221

332

342

343

443

453

分别减去最右边的数

000

110《----

110

120

010
110《----

120

就可以发现是2和6是最远的相同数字,那么只用6-2=4即可算出答案

 

那到底为什么这么做就对了呢?

为什么两个数一样就得到了正确解了呢。

可以这么理解,当两个数相同时,说明在这两个数之间出现的数在每个特征上出现的数目相同,否则是不会两个数相同的。因为只有最右边的那个数增加了和左边所有的数增加的数字相同,他们才会减去最右边的数,出现相同

 

接着可以用HASH,也可以用MAP,我觉得不需要用MULTIMAP,因为只需要记录每个数字形式出现的最早时期即可。

注意给HASH函数加上0000000000这种情况

 

 

#include<stdio.h>
#include<string.h>
const int N=100100;
const int prime=100003;
int sum[N][32],c[N][32];
int hash[N];
int hashcode(int* v,int k)
{
    int p;
    for(int i=1;i<=k;i++)  p=((p<<2)+(v[i]>>4))^(v[i]<<10);
    p=p%prime;
    if(p<0)  p=p+prime;
    return p;
}
int main()
{
    //freopen("lineup.10.in","r",stdin);
    //freopen("out.txt","w",stdout);
    int n,k;
    int ans=0;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        memset(sum,0,sizeof(sum));
        memset(hash,-1,sizeof(hash));
        memset(c,0,sizeof(c));
        hash[hashcode(c[0],k)]=0;
        ans=0;
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            for(int j=1;j<=k;j++)
            {
                sum[i][j]=sum[i-1][j]+x%2;
                c[i][j]=sum[i][j]-sum[i][1];
                x=x>>1;
            }
           int p=hashcode(c[i],k);
           while(hash[p]!=-1)
            {
                int j;
                for(j=1;j<=k;j++)
                    if(c[i][j]!=c[hash[p]][j])  break;
                if(j==k+1)
                {
                    if(i-hash[p]>ans)  ans=i-hash[p];
                    break;
                }
                p++;
            }
            if(hash[p]==-1)  hash[p]=i;
        }
        printf("%d/n",ans);
    }
    return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值