標籤:blog 資料 2014 os for io
題意:給出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; }