题意:给出n个二进制串,可以把其中的一些0和1反转(即0变1,1变0),找出转化后n个串中的最大值和最小值的差值。
分析:思路就是把所有的串和反转的存在一个数组中,然后排序,找最大值和最小值的差,(如果是同一个串反转的就找第二大的和最小的或第二小和最大的中的最大值)。注意假如只有一个串的话结果为0
DEBUG:
这题写了好久
1.第一次用vim,很爽,但是还没熟练
2.忽视了这题的范围,显然要用longlong
3.用了longlong后还WA,用脚本跑出来数据发现在longlong下,min的值要变成(1<<63)-1但是不能这么写,应该写个longlong 是1<<30,然后在这个longlong基础上再移位
最后不得不说句 BNUOJ真的比POJ好看很多哈
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
using namespace std;
char str[111111][222];
long long tmp=1<<30;
const long long MAX_LONG=(tmp<<33)-1;
long long num[111111];
long long m,n;
void getRev(char* to,char* source,long long len)
{
for(long long i=0;i<len;i++)
to[i]=source[i]=='0'?'1':'0';
to[len]='\0';
}
long long getNum(char* s,long long len)
{
long long sum=0;
for(long long i=0;i<len;i++)
{
sum*=2;
sum+=s[i]-'0';
}
return sum;
}
int main()
{
long long test;
cin>>test;
for(long long time=1;time<=test;time++)
{
cin>>m>>n;
for(long long i=1;i<=m;i++)
cin>>str[i];
/*if(m==1)
{
printf("Case #%d: 0\n",time);
continue;
}*/
for(long long i=m+1;i<=2*m;i++)
getRev(str[i],str[i-m],n);
long long minn=MAX_LONG;long long maxn=0;
for(long long i=1;i<=2*m;i++)
num[i]=getNum(str[i],n);
long long max1=0,max1index,min1=MAX_LONG,min1index;
long long max2=0,max2index,min2=MAX_LONG,min2index;
for(long long i=1;i<=2*m;i++)
{
if(num[i]>max1)
{
max1=num[i];
max1index=i;
}
if(num[i]<min1)
{
min1=num[i];
min1index=i;
}
}
for(long long i=1;i<=2*m;i++)
{
if(i!=max1index&&num[i]>max2)
{
max2=num[i];
max2index=i;
}
if(i!=min1index&&num[i]<min2)
{
min2=num[i];
min2index=i;
}
}
if(abs(min1index-max1index)!=m)
{
maxn=max1;
minn=min1;
}
else
{
if(max1-min2>max2-min1)
{
//cout<<"1"<<endl;
maxn=max1;minn=min2;
}
else
{
//cout<<"2"<<endl;
maxn=max2;minn=min1;
}
}
//cout<<maxn<<' '<<minn<<endl;
printf("Case #%lld: %lld\n",time,maxn-minn);
}
return 0;
}