题意:
代码操作如下:
1、先将十进制数转换成二进制数记录保存。
2、然后逐行累加,得出到某只牛时某种特征出现了几次。
3、每行减去第一个数,得出一个序列,若两头牛之间是平衡区间的话,各个特征的增长数是相等的,及减掉第一个数得出来的序列是相等的。
4、寻找距离最远的两个相等的序列,得出答案。
我们可以由样例举例:
转换成二进制特征值为:
数字 特征值 第几头牛
7 1 1 1 1
6 0 1 1 2
7 1 1 1 3
2 0 1 0 4
1 1 0 0 5
4 0 0 1 6
2 0 1 0 7
按行累加得:
1 1 1
1 2 2
2 3 3
2 4 3
3 4 3
3 4 4
3 5 4
都减去第一列得:
0 0 0
0 1 1
0 1 1
0 2 1
0 1 0
0 1 1
0 2 1
所以说 最大区间是 6-2 = 4.
有一种特殊情况就是当到了某一行出现全都是零的情况,例如:
0 1 2 1 1 0 2
0 0 0 2 1 1 1
0 0 0 0 0 0 0
我们需要在所有序列之前加一行0以方便比较。
寻找相同序列的时候可以使用快排函数,这样比较方便,详细见代码。
下面是代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h> 2 #include<stdlib.h> 3 struct node 4 { 5 int d[30]; 6 int in; 7 }cow[100005]; 8 int n,k; 9 10 int cmp(int x) 11 { 12 for(int i=0; i<k; i++) 13 { 14 if(cow[x].d[i]!=cow[x-1].d[i]) 15 { 16 return 0; 17 } 18 } 19 return 1; 20 } 21 22 int cmp2(const void *a,const void *b)//Qsort比较函数; 23 { 24 struct node *aa=(struct node *)a; 25 struct node *bb=(struct node *)b; 26 for(int i=0; i<k; i++) 27 { 28 if(aa->d[i]!=bb->d[i]) 29 { 30 return aa->d[i]-bb->d[i]; 31 } 32 } 33 return aa->in-bb->in; 34 } 35 36 int main() 37 { 38 int i,j,t ; 39 while(~scanf("%d %d",&n,&k))//多组输入 40 { 41 int x,y,max1; 42 for(i=0;i<k;i++) 43 cow[0].d[i]=0; 44 cow[0].in=0; 45 for(i=1;i<=n;i++) 46 { 47 scanf("%d",&t); 48 for(j=0;j<k;j++) 49 { 50 cow[i].d[j]=t%2;//将十进制数化为二进制,存入cow数组 51 t=t>>1; 52 } 53 cow[i].in=i;//记录牛的标号,以便排序后寻找; 54 for(j=0;j<k;j++) 55 cow[i].d[j]+=cow[i-1].d[j];//逐个累加 56 for(j=1;j<k;j++) 57 cow[i].d[j]-=cow[i].d[0];//减去第一个 58 cow[i].d[0]=0; 59 } 60 qsort(cow,n+1,sizeof(cow[0]),cmp2);//快排 61 x=0,y=0,max1=0; 62 for(i=1;i<=n;i++)//寻找最大距离 63 { 64 if(cmp(i)) 65 { 66 y=i; 67 } 68 else 69 { 70 if(max1<cow[y].in-cow[x].in) 71 { 72 max1=cow[y].in-cow[x].in; 73 } 74 x=i; 75 y=i; 76 } 77 } 78 if(max1<cow[y].in-cow[x].in) 79 { 80 max1=cow[y].in-cow[x].in; 81 } 82 printf("%d ",max1); 83 } 84 return 0; 85 }