位运算
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 }