位运算

1. Team Formation

链接:https://cn.vjudge.net/contest/157826#problem/B

问题:N个数,找出符合条件的对的个数。符合条件的一对为:两个数 相异或 的值大于该两个数,则符合。

例如:

3

1 2 3

输出: 1

解释: 1 异或 2 = 3  3>max(1,2) 符合

   1 异或 3 = 2 2<max(1,3) 不符合

     2 异或 3 = 1 1<max(2,3) 不符合

解题思路:

[0. 小N可以,大N会超时,两个for 暴力,if(max(s[i],s[j])<s[i]^s[j] )sum++; ]

正解:将每个数从其二进制的角度分析,考虑两个数的1的最高位,如该两个数的最高位在不同位置,且数小的最高位不在大数的1的位置,则该对数为符合条件。

例如:1 5 不符合, 但2 5 就符合。其余的看代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int s[100002];
 4 int mx[100002];
 5 int al[100002][32];
 6 int br[32];
 7 int main()
 8 {
 9     int T,n,tem;
10     scanf("%d",&T);
11     while(T--)
12     {
13         memset(s,0,sizeof(s));
14         memset(mx,0,sizeof(mx));
15         memset(al,0,sizeof(al));
16         memset(br,0,sizeof(br));
17         scanf("%d",&n);
18         for(int i=0; i<n; i++)
19         {
20             scanf("%d",&s[i]);
21             tem=s[i];
22             while(tem>>=1)mx[i]++;
23         }
24         for(int i=0; i<n; i++)
25             br[mx[i]]++;
26 
27         for(int i=0,j=0; i<n; i++)
28         {
29             while(s[i])
30             {
31                 al[i][j++]=s[i]%2;
32                 s[i]/=2;
33             }
34             j=0;
35         }
36         int sum=0;
37         for(int i=0; i<n; i++)
38         {
39             for(int j=mx[i]; j>=0; j--)
40                if(!al[i][j])
41                sum+=br[j];
42         }
43         printf("%d\n",sum);
44     }
45       return 0;
46 }
View Code

 

posted @ 2017-04-08 22:18  马丁黄瓜啊  阅读(190)  评论(0编辑  收藏  举报