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
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
Sample Input
7 3 7 6 7 2 1 4 2
Sample Output
4
Hint
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;
}