题意:给出n个数,在其中任意挑出两个数进行异或,判断有多少种情况使得异或的值大于原数。
链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5518
思路:转化为二进制,对位进行拆分,求出每一位的0的个数a以及二进制位数b,输出sum(a*b)
注意点:无
以下为AC代码:
Run ID | Submit Time | Judge Status | Problem ID | Language | Run Time(ms) | Run Memory(KB) | User Name |
3945006 | 2015-04-26 18:38:13 | Accepted | 3870 | C++0x | 380 | 272 | luminus |
/*
***********************************************
*# @Author : Luminous11 (573728051@qq.com)
*# @Date : 2015-04-26 18:25:24
*# @Link : http://blog.youkuaiyun.com/luminous11
***********************************************
*/
#include <bits/stdc++.h>
#define clr(a, v) memset( a , v , sizeof(a) )
using namespace std;
const double eps = 1e-10;
const double pi = acos(-1.0);
int num0[35];
int num1[35];
void calc ( int tmp )
{
int p = 1;
while ( tmp ){
if ( ( tmp & 1 ) == 0 ){
num0[p] ++;
}
tmp >>= 1;
p ++;
}
num1[p-1] ++;
}
int main()
{
//ios::sync_with_stdio ( false );
int T;
scanf ( "%d", &T );
while ( T -- ){
int n;
scanf ( "%d", &n );
memset ( num0, 0, sizeof ( num0 ) );
memset ( num1, 0, sizeof ( num1 ) );
int tmp;
for ( int i = 0; i < n; i ++ ){
scanf ( "%d", &tmp );
calc ( tmp );
}
long long ans = 0;
for ( int i = 0; i < 35; i ++ ){
ans += (long long)num0[i] * (long long)num1[i];
}
printf ( "%lld\n", ans );
}
return 0;
}