POJ 3274 Gold Balanced Lineup
说实在话对于英文渣渣的我读题真的很难。
下面是题目大意,对提供者表示感谢。
代码操作如下:
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以方便比较。
寻找相同序列的时候可以使用快排函数,这样比较方便,详细见代码。
下面是代码:
#include <stdio.h> #include <stdlib.h> int k; struct node { int d[30]; int in ; } cow[100005]; bool cmp(int x) { for(int i=0; i<k; i++) { if(cow[x].d[i]!=cow[x-1].d[i]) { return 0; } } return 1; } int cmp2(const void *a,const void *b)//Qsort的比较函数 { struct node *aa=(struct node *)a; struct node *bb=(struct node *)b; for(int i=0; i<k; i++) { if(aa->d[i]!=bb->d[i]) { return aa->d[i]-bb->d[i]; } } return aa->in-bb->in; } int main() { int n; while(scanf("%d%d",&n,&k)!=EOF) { int a,i,j,x,y,max1=0; for(i=0;i<k;i++) { cow[0].d[i]=0; } cow[0].in=0; for(i=1; i<=n; i++) { scanf("%d",&a); for(j=0; j<k; j++) { cow[i].d[j]=a%2; a=a>>1; } cow[i].in=i;//记录这是第几头牛,方便排序后寻找。 for(j=0; j<k; j++) { cow[i].d[j]+=cow[i-1].d[j]; } for(j=1; j<k; j++) { cow[i].d[j]-=cow[i].d[0]; } cow[i].d[0]=0; } qsort(cow,n+1,sizeof(cow[0]),cmp2); x=0,y=0,max1=0; for(i=1; i<=n; i++) { if(cmp(i)) { y=i; } else { if(max1<cow[y].in-cow[x].in) { max1=cow[y].in-cow[x].in; } x=i; y=i; } } if(max1<cow[y].in-cow[x].in) { max1=cow[y].in-cow[x].in; } printf("%d\n",max1); } return 0; }