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 */
View Code

 

posted @ 2015-07-26 20:12  鼠宝宝  阅读(247)  评论(1编辑  收藏  举报