ZOJ 3870 Team Formation
2016-04-29 21:15
295 查看
题目链接:http://icpc.moe/onlinejudge/showProblem.do?problemId=5518
题意:给出n个数字,从中任选两个数,问有多少种组合可以达到所选的两个数的异或运算值比这两个数都大。
题意很简单,对于异或运算的题目我们一般采取贪心的思想。
首先分析,怎么样才能使两个数的异或运算值比他们两个数都大,因为异或运算是1^1 = 0,1^0 = 1,0^0 = 0,我们想要达到增大的效果,那么肯定是运用1^0 = 1的性质,所以不难想到,如果两个数中小的那个数最高位的1在大的那个数中是0的话,那么两个数的异或运算值就会增大。
得到这个贪心策略之后我们第一步便是统计这n个数中每一个的最高位1所在的位置出现的次数,然后再遍历每一个数,每一个数满足条件的个数就是最高位在这个数所含0的位置上的个数和(有点绕口啊,小编没法讲的更精细了,大家仔细理解理解)。
题意:给出n个数字,从中任选两个数,问有多少种组合可以达到所选的两个数的异或运算值比这两个数都大。
题意很简单,对于异或运算的题目我们一般采取贪心的思想。
首先分析,怎么样才能使两个数的异或运算值比他们两个数都大,因为异或运算是1^1 = 0,1^0 = 1,0^0 = 0,我们想要达到增大的效果,那么肯定是运用1^0 = 1的性质,所以不难想到,如果两个数中小的那个数最高位的1在大的那个数中是0的话,那么两个数的异或运算值就会增大。
得到这个贪心策略之后我们第一步便是统计这n个数中每一个的最高位1所在的位置出现的次数,然后再遍历每一个数,每一个数满足条件的个数就是最高位在这个数所含0的位置上的个数和(有点绕口啊,小编没法讲的更精细了,大家仔细理解理解)。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 100000+5; int a[maxn],bit[35];// bit[i]表示有多少个数的最高位的1在第i位上 void solve(int x) { int l = 31; while(l >= 0) { if(x & (1<<l)) { bit[l]++; return ; } l--; } } int main() { int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); memset(bit,0,sizeof(bit)); for(int i=0; i<n; i++) { scanf("%d",&a[i]); solve(a[i]); } int ans = 0; for(int i=0; i<n; i++) { int l = 31; while(l >= 0) { if(a[i] & (1<<l)) break; l--; } while(l >= 0) { if(!(a[i] & (1<<l))) ans += bit[l]; l--; } } printf("%d\n",ans); } }
相关文章推荐
- Linux使用小技巧
- Activity生命周期
- Android小菜鸟向大神进攻的奋斗记(一)之Android最全的源码下载
- 括号配对问题
- Highcharts下载与使用_数据报表图2
- 基础卷_异常篇_第2集 异常的基本处理方式
- 括号配对问题
- 不起眼的 z-index 却能牵扯出这么大的学问(转)
- 杭州4--29.关于sqltest_beego的一些注意点和分页JS
- 我经历的IT公司面试及离职感受(转)
- 机器学习模型(一) GBDT
- Java模块 -- BigDecimal 支持任何精度的定点数
- 浅谈对S2SH,SSM框架的理解
- HDU 1233 还是畅通工程
- scala学习第二弹:函数式编写思想
- ImageLoader加载本地图片
- UVA 11134
- Spring Aop原理分析(二) - Aop的拦截器和通知
- Android 监听短信内容变化,并发送到自己的手机
- Android学习之AndroidManifest.xml清单之<uses-feature>