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

 

你可能感兴趣的:(bit)