cdoj 491 Tricks in Bits
//无脑爆居然能过!!!!!
解:其实正解也是暴力,但是可以证明在n>6时答案一定为零。
第一步:对于任意两个数他们的二进制数要么有一半+的位是相同的,要么有一半+的位是不同的,于是首先使用与运算和异或运算一定能使一半以上的位数变成0。
那么设第一步得到的数字为x,接下来我们对x与下一个数c做与运算,x上已经为0的位数一定仍为0。
对于剩下x中为1的位数,如果c中也为1的个数比较多,那么我们首先取反再做运算,如果c中为0的位数比较多那么直接做与运算,如此一定可使x中为1的位数中一半以上的位数变为0
即每部都可以使1的个数减少一半以上,因此对于64位二进制数,最多只需要7步就可以让所以的位数全部变为0.
所以对于n>6直接输出0.对于n<=6,dfs求解
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #include<stack> 11 #include<string> 12 #define LL long long 13 #define ULL unsigned long long 14 15 const int MAXN=0; 16 const int MAXM=0; 17 const int INF=2000000000;//careful because of floyed and so on 18 const int MOD=1000000007; 19 const unsigned long long UINF=18000000000000000000; 20 21 using namespace std; 22 23 int n,T; 24 ULL a[107]; 25 ULL ans; 26 27 void dfs(int t,ULL num){ 28 if (t>n){ 29 ans=min(ans,num); 30 return; 31 } 32 if (ans==0) return; 33 if (num==0){ 34 ans=0; 35 return; 36 } 37 dfs(t+1,num&(a[t])); 38 dfs(t+1,num&(~a[t])); 39 dfs(t+1,num^(a[t])); 40 dfs(t+1,num^(~a[t])); 41 dfs(t+1,num|(a[t])); 42 dfs(t+1,num|(~a[t])); 43 } 44 45 int main(){ 46 scanf("%d",&T); 47 for (int cas=1;cas<=T;cas++){ 48 scanf("%d",&n); 49 ans=UINF; 50 for (int i=1;i<=n;i++) scanf("%llu",&a[i]); 51 if (n>6){ 52 ans=0; 53 } 54 else{ 55 dfs(2,a[1]); 56 dfs(2,~a[1]); 57 } 58 printf("Case #%d: %llu\n",cas,ans); 59 } 60 return 0; 61 } 62 /* 63 2 64 3 65 1 2 3 66 2 67 3 6 68 */