pku 3274 Gold Balanced Lineup

http://poj.org/problem?id=3274 

感觉这都题目好无语,很早就开始看题目,可是看不懂就放下了,后来又看,还是没看懂又放下了。这样来来回回的以至于昨天做,还是看的discuss里面的才知道了怎么回事。

这个就是给你n头牛和k个种类,然后会给你n个数字,这n个数字当你把他们转化为2进制数时,他们的数码个数不会超过给的种类个数,比如说样例给的种类 3 ,然后n个数里最大的那个是7,2进制数为111.然后让你找的就是连续的第i头和第j头中,满足这些牛的k种特征个数是一样的

这个也许看了还是不大明白,看看下面的转化方式吧

111      111      000
110      221      110
111      332<     110
010      342      120
001      342      120
100      443<     110
010      453      120
先看第一列,第二个111 到 100 把他们各列相加,最后得到一行2 2 2 ,这就题目最后给的提示的意思,这四个是连续的,而且它们中每个特征都出现了两次,下面是变化求结果的过程
从第一列到第二列是每一个下面的数加上紧挨这它上面的数,第二列到第三列是每一行的数都减去它们最右边的数,然后,找出俩个相距最远的字符串是一样的两个串,它们的距离就是所求的答案
 1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 #include<iostream>
5 using namespace std;
6 #define N 32
7 #define M 100010
8 int k;
9 struct NODE
10 {
11 int d[N],p; // d用来记录二进制数,p用来记录为准
12 bool operator < (const NODE &x) const // 从小到大排序函数
13 {
14 int i;
15 for(i=0;i<k-1;i++)
16 if(d[i] != x.d[i]) return d[i] < x.d[i];
17 return p < x.p;
18 }
19 bool operator == (const NODE &x) const // 因为下面要比较 node 型数组是否相等,所以自定义一个这样的函数
20 {
21 int i;
22 for(i=0;i<k-1;i++)
23 if(d[i] != x.d[i]) return false;
24 return true;
25 }
26 };
27 NODE a[M];
28 int main()
29 {
30 int n,i,j;
31 cin>>n>>k;
32 memset(a,0,sizeof(a));
33 int x;
34 for(i=1;i<=n;i++)
35 {
36 a[i].p=i;
37 cin>>x;
38 for(j=k-1;j>=0;j--) //位运算转化二进制数
39 {
40 a[i].d[j] = x & 1;
41 x = x >> 1;
42 }
43 }
44 for(i=1;i<=n;i++) //第一次变化
45 {
46 for(j=0;j<k;j++)
47 a[i].d[j]+=a[i-1].d[j];
48 }
49 for(i=1;i<=n;i++) // 第二次变化
50 {
51 for(j=0;j<k;j++)
52 a[i].d[j]-=a[i].d[k-1];
53 }
54 sort(a,a+n+1);
55 a[n+1].d[0]=1<<30;
56 i=j=0;
57 int ans=0;
58 while(i<=n)  // 找最长的距离
59 {
60 int t=a[i].p;
61 int tt;
62 while(a[i]==a[j])
63 j++;
64 tt=a[j-1].p;
65 ans=max(ans,tt-t);
66 i=j;
67 }
68 cout<<ans<<endl;
69 return 0;
70 }


原文地址:https://www.cnblogs.com/fxh19911107/p/2399741.html