2015 ACM/ICPC合肥网赛&HDU5491 The Next
2015-09-28 16:26
411 查看
传送门
题意:给出一个数字n,其二进制表示中1的个数在a~b之间,求出个数在a~b之间的比n大的最小的数。
思路:首先用一个数组存储n的二进制数,从低到高枚举0出现的位置,若把该位置为1,该位之前的全部置0后,若所有1的个数仍然比b大,则向后枚举下一个为0的位置,直到最高位。
若1的总数大于a小于b,则直接把该位置为1,之前为0,这个数就是最小的数。
若总数小于a,则从最低位开始往上设置1,由此保证这个数是满足要求的最小的数。
(语文实在不好,没看懂的结合代码看吧)
题意:给出一个数字n,其二进制表示中1的个数在a~b之间,求出个数在a~b之间的比n大的最小的数。
思路:首先用一个数组存储n的二进制数,从低到高枚举0出现的位置,若把该位置为1,该位之前的全部置0后,若所有1的个数仍然比b大,则向后枚举下一个为0的位置,直到最高位。
若1的总数大于a小于b,则直接把该位置为1,之前为0,这个数就是最小的数。
若总数小于a,则从最低位开始往上设置1,由此保证这个数是满足要求的最小的数。
(语文实在不好,没看懂的结合代码看吧)
#include <cstdio> #include <iostream> #include <cstring> #include <cmath> using namespace std; const int maxn = 55; int T,a,b,num[maxn],sum[maxn],cases = 0; long long n,t; int main(){ scanf("%d",&T); while(T--){ memset(num,0,sizeof(num)); memset(sum,0,sizeof(sum)); scanf("%lld%d%d",&n,&a,&b); t=n; int all = 0,pos = 0; while(t){ if(t&1) all++,num[pos]=1; t>>=1;pos++; } sum[pos-1]=num[pos-1]; for(int i=pos-2;i>=0;i--) sum[i]+=sum[i+1]+num[i]; // for(int i=pos-1;i>=0;i--) // cout<<num[i]<<endl; for(int i=0;i<=pos;i++){ if(!num[i]){ int tempall = sum[i]+1; // cout<<tempall<<" "<<b<<endl; // cout<<"--------------"<<endl; if(tempall>b) continue; long long ans = 0; int post = 0; while(tempall<a){ ans += pow(2,post); post++; tempall++; } // cout<<ans<<endl; ans+=pow(2,i); // cout<<ans<<endl; for(int j=i+1;j<pos;j++) ans += num[j]*pow(2,j); printf("Case #%d: %lld\n",++cases,ans); break; } } } return 0; }
相关文章推荐
- 寻找字符串中最长回文——Manacher算法及其Java实现
- 数据结构和算法学习(2)-时间复杂度
- 字符串压缩
- Java使用jdbc连接和操作mysql的例子
- android学习地址和文章总结
- 晨遇
- 差分约束POJ3159Candies(spfa+stack)解题报告
- windows多线程编程简介(2)
- UVA 815 Flooded!
- SQL中获取树形结构所有子级数据
- Java基础知识强化之IO流笔记04:throw和throws的区别
- fseek函数
- Linux学习篇-SVN命令详解
- noip2011 计算系数 (幂方取模+组合数取模)
- 1014. 福尔摩斯的约会 (20)
- 【HTML】空格
- AngularJS报错:[$compile:tpload]
- JavaScript高级程序设计之函数表达式之递归第7.1讲笔记
- 【Cocos2d-x】spirit frame
- EditPlus正则表达式 替换字符串开头