zoj 3870 Team Formation
题意:
给出n个数,问做多可以找到多少对数字A,B,使得A xor B > max(A,B)。
思路:
感谢mzjj教本弱智。
对于一个数,只考虑小于它的数字。
假设对于一个数字x 11001001,对于从最高位开始的连续的1,满足条件的数y的这位一定不能为1,从碰到的第一位0开始:这一位就可以是1,后面无论是什么都可以满足条件;
如果这位不为1,那么直到碰到下一个0之前,都不能是1。
所以可以从小到大枚举,按最高位分组,对于当前来到的x,枚举它的0的位有多少,答案加上以这位为最高位的数字的个数。
然后把这个数字加进分组中。
一开始把b数组只开了10,以为10的9次方最多10位,确实是,但是那是10进制,二进制就是32位了,睿智了Orz。
我的代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 using namespace std; 5 const int N = 1e5 + 10; 6 int a[N]; 7 int b[35]; 8 int main() 9 { 10 int t; 11 scanf("%d",&t); 12 while (t--) 13 { 14 memset(b,0,sizeof(b)); 15 int n; 16 scanf("%d",&n); 17 for (int i = 0;i < n;i++) 18 { 19 scanf("%d",&a[i]); 20 } 21 sort(a,a+n); 22 long long ans = 0; 23 for (int i = 0;i < n;i++) 24 { 25 int x = a[i]; 26 int cnt = 0; 27 while (x) 28 { 29 if (!(x & 1)) ans += b[cnt]; 30 cnt++; 31 x >>= 1; 32 } 33 if (cnt == 0) continue; 34 b[cnt-1]++; 35 } 36 printf("%lld\n",ans); 37 } 38 return 0; 39 }
学长的代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int N = 1e5 + 5; 5 int T, n; 6 int a[N]; 7 int cnt[33]; 8 9 int main() { 10 scanf("%d", &T); 11 while(T--) { 12 scanf("%d", &n); 13 for(int i = 0; i < n; i++) { 14 scanf("%d", &a[i]); 15 } 16 sort(a, a+n); 17 memset(cnt, 0, sizeof(cnt)); 18 LL ans = 0; 19 for(int i = 0; i < n; i++) { 20 int x = a[i]; 21 int b = 31 - __builtin_clz(x);//返回左起第一个‘1’之前0的个数。 22 for(int j = 0; j < b; j++) { 23 if(~x&(1<<j)) ans += cnt[j]; 24 } 25 cnt[b]++; 26 } 27 printf("%lld\n", ans); 28 } 29 return 0; 30 }
康复训练中~欢迎交流!