给定一堆二进制数,可以把某些数变化为其NOT形式
NOT形式对应原字符串中1,0变换
因为同一个数不能使用两次,所以我们要找到最小、 次小、 最大、 次大
比较最大-次小和次大-最小的值即可
代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXN 110
#define LL long long
#define INF 0x7fffffffffffffff
using namespace std;
int T, n, k;
LL a[5];
char str[MAXN], strtmp[MAXN];
LL Not_val(char str[]) {//用于得到当前二进制对应十进制数值
LL ans = 0ll;
LL tmp = 1ll;
for(int i=k-1; i>=0; --i) {
ans += (str[i]-'0')*tmp;
tmp <<= 1;
}
return ans;
}
void Not(char str1[], char str2[]) {//把str2的NOT形式保存在str1中
for(int i=0; i<k; ++i)
str1[i] = '1'-str2[i]+'0';
return ;
}
int main(void) {
LL fmin, smin, fmax, smax, tmp1, tmp2;
scanf("%d", &T);
for(int t=1; t<=T; ++t) {
scanf("%d%d", &n, &k);
fmin = smin = INF;
fmax = smax = -1;
while(n--) {
scanf("%s", str);
strcpy(strtmp, str);
Not(strtmp, str);
tmp1 = Not_val(str);
tmp2 = Not_val(strtmp);
a[0] = fmin;
a[1] = smin;
a[2] = tmp1;
a[3] = tmp2;
sort(a, a+4);//思想比较巧妙,可以想一下!
fmin = a[0];
smin = a[1];
a[0] = fmax;
a[1] = smax;
a[2] = tmp1;
a[3] = tmp2;
sort(a, a+4);
fmax = a[3];
smax = a[2];
/*
cout << str << endl;
cout << strtmp << endl;
cout << tmp2 << endl;
cout << tmp1 << endl;
*/
}
// printf("fmax = %lld\tsmin = %lld\tsmax = %lld\tfmin = %lld\n", fmax, smin, smax, fmin);
printf("Case #%d: %lld\n", t, max((fmax-smin), (smax-fmin)));
}
return 0;
}