POJ3252 Round Numbers【组合问题】
2015-08-31 21:34
477 查看
题目链接:
http://poj.org/problem?id=3252
题目大意:
给你两个十进制数 A 和 B,求其对应闭区间 [A,B] 内有多少个Round Numbers。
Round Numbers 是指:如果一个十进制数对应的二进制数中的 0 的个数多于 1 的
个数,则该数就是一个 Round Numbers。
解题思路:
参考博文:http://www.cnblogs.com/lyy289065406/archive/2011/07/31/2122758.html
计算闭区间 [A,B] 内有多少个Round Numbers,只需要分别求出[0,A] 内有多少
个Round Numbers,[0,B+1] 内有多少个Round Numbers,然后后者减去前者即
可。
那么如何来求[0,A]闭区间的 Round Numbers。
第一步先把 A 转换为二进制数,存入数组 Binary[] 数组中,其中 Binary[0]存放二进
制数数位长度。
再分为两部分计算区间内 Round Numbers:
①长度小于二进制数位长度 Binary[0] 的部分:
这部分的最高位肯定为 1,剩下数位可供放入数字的位数为 Binary[0]-1,从低位向高
位考虑情况。方案数和sum要加上各种放置情况。
for(int i = 1; i < Binary[0]-1; ++i)
{
for(int j = i/2+1; j <= i; ++j)
sum += C[i][j];
}
②长度等于二进制数位长度 Binary[0]的部分:
从高位向低位搜索除最高位外置为 1 的数位,并统计 1 的位数,然后方案数 sum
加上各种情况。
AC代码:
http://poj.org/problem?id=3252
题目大意:
给你两个十进制数 A 和 B,求其对应闭区间 [A,B] 内有多少个Round Numbers。
Round Numbers 是指:如果一个十进制数对应的二进制数中的 0 的个数多于 1 的
个数,则该数就是一个 Round Numbers。
解题思路:
参考博文:http://www.cnblogs.com/lyy289065406/archive/2011/07/31/2122758.html
计算闭区间 [A,B] 内有多少个Round Numbers,只需要分别求出[0,A] 内有多少
个Round Numbers,[0,B+1] 内有多少个Round Numbers,然后后者减去前者即
可。
那么如何来求[0,A]闭区间的 Round Numbers。
第一步先把 A 转换为二进制数,存入数组 Binary[] 数组中,其中 Binary[0]存放二进
制数数位长度。
再分为两部分计算区间内 Round Numbers:
①长度小于二进制数位长度 Binary[0] 的部分:
这部分的最高位肯定为 1,剩下数位可供放入数字的位数为 Binary[0]-1,从低位向高
位考虑情况。方案数和sum要加上各种放置情况。
for(int i = 1; i < Binary[0]-1; ++i)
{
for(int j = i/2+1; j <= i; ++j)
sum += C[i][j];
}
②长度等于二进制数位长度 Binary[0]的部分:
从高位向低位搜索除最高位外置为 1 的数位,并统计 1 的位数,然后方案数 sum
加上各种情况。
int Zero = 0; for(int i = Binary[0]-1; i >= 1; --i) { if(Binary[i]) { for(int j = (Binary[0]+1)/2-(Zero+1); j <= i-1; ++j) sum += C[i-1][j]; } else Zero++; }
AC代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; int C[33][33]; void ZuHe() { C[0][0] = C[1][0] = C[1][1] = 1; for(int i = 2; i <= 32; ++i) { C[i][0] = C[i][i] = 1; for(int j = 1; j < i; ++j) C[i][j] = C[i-1][j] + C[i-1][j-1]; } } int Binary[35]; void Change(int N) { Binary[0] = 0; while(N) { ++Binary[0]; Binary[Binary[0]] = N%2; N /= 2; } } int Solve(int N) { Change(N); int sum = 0; for(int i = 1; i < Binary[0]-1; ++i) { for(int j = i/2+1; j <= i; ++j) sum += C[i][j]; } int Zero = 0; for(int i = Binary[0]-1; i >= 1; --i) { if(Binary[i]) { for(int j = (Binary[0]+1)/2-(Zero+1); j <= i-1; ++j) sum += C[i-1][j]; } else Zero++; } return sum; } int main() { ZuHe(); int A,B; while(~scanf("%d %d",&A,&B)) { printf("%d\n", Solve(B+1)-Solve(A)); } return 0; }
相关文章推荐
- linux源码包安装过程
- android传递数据方式3--通过剪切板传类
- 软件测试概念与基本流程
- ARM 体系结构与汇编指令
- java学习笔记之面向对象
- DP hduHDU 5119
- Testlink实验心得
- Mysql安装与配置
- 使用vmware虚拟机安装virt-manager unable to connect to libvirt的处理办法
- 《暗时间》读书笔记
- Codeforces 166E Tetrahedron
- 一个数被3除余2,被5除余3,被7除余2,求满足条件的前N个数
- Ubuntu12.02 NFS安装与OK6410
- 软件测试基础_什么是软件测试
- 动态规划6-背包问题
- NSMutableString可变字符串的定义及常用方法
- 还是上边一个问题
- 最简单的单身模式
- Struts2系列-Struts2简介和原理
- JAVA语言中数组的冒泡排序方法