ZOJ - 3870-Team Formation二进制,位运算
传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3870
题意:找出一个数列中的两个数,所有通过异或和使得结果同时大于这两个数;
思路:先找出每个数在二进制下最高位 1 所在的下标;
对于每个数,
1/ 判断这个数的最后一位是不是 0,如果是 0,说明可以 和 最高位是这个位子(1)的数进行异或得到更大的数;
结果加上有多少个这样的数;
2/ 对这个数进行( >>1 ), 右移一位的操作;
ac代码
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 100009; int a[maxn],sum[100]; int get(int n) { int s=n,re=0; while(s) { s>>=1; re++; } return re; } int main(){ //freopen("in","r",stdin); int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); memset(sum,0,sizeof(sum)); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); sum[get(a[i])]++; } long long ans=0; for(int i=1;i<=n;i++) { int wei=1; while(a[i]) { if((a[i] & 1 )== 0) { ans+=sum[wei]; } a[i]>>=1; wei++; } } printf("%lld\n",ans); } return 0; }
skr