hdu5491 The Next(合肥网赛)
2015-09-27 18:08
288 查看
The Next
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 21 Accepted Submission(s): 10
Problem Description
Let L
denote the number of 1s in integer D
’s
binary representation. Given two integers S
1
and S
2
,
we call D
a WYH number if S
1
≤L≤S
2
.
With a given D
,
we would like to find the next WYH number Y
,
which is JUST larger than D
.
In other words, Y
is the smallest WYH number among the numbers larger than
D
.
Please write a program to solve this problem.
Input
The first line of input contains a number
T
indicating the number of test cases (T≤300000
).
Each test case consists of three integers D
,
S
1
,
and S
2
,
as described above. It is guaranteed that 0≤D<2
31
and D
is a WYH number.
Output
For each test case, output a single line consisting of “Case #X: Y”.
X
is the test case number starting from 1. Y
is the next WYH number.
Sample Input
3 11 2 4 22 3 3 15 2 5
Sample Output
Case #1: 12 Case #2: 25 Case #3: 17
Source
2015 ACM/ICPC Asia Regional Hefei Online
题意:L为D的二进制数中1的个数,然后求s1<=L<=s2的下一个D。
分析:把D的二进制数用数组存起来,然后记录末尾0(ret)和1(cnt)的个数,然后一位一位的找,比较水,只能想到这么暴力的方法,详解见代码。
#include <iostream> #include <cstdio> #include <cstring> #include <stack> #include <queue> #include <map> #include <set> #include <vector> #include <cmath> #include <algorithm> using namespace std; const double eps = 1e-6; const double pi = acos(-1.0); const int INF = 0x3f3f3f3f; const int MOD = 1000000007; #define ll long long #define CL(a) memset(a,0,sizeof(a)) ll ans; int d,s1,s2; int a[33]; int main () { int T; scanf ("%d",&T); for (int ii=1; ii<=T; ii++) { scanf ("%d%d%d",&d,&s1,&s2); ans=d; printf ("Case #%d: ",ii); int k=1,sum=0; CL(a); while (d) { a[k++]=d&1; if (d&1) sum++;//总共有多少个1 d=d>>1; } bool flag=false; int t,cnt=0,ret=0; for (int i=1; i<=k; i++) { if (!flag&&a[i]==0) ret++;//末尾的0数 if (a[i]==1) {flag=true; cnt++;}//末尾的1数 if (flag&&a[i]==0) {t=i; break;} } //cout<<ret<<" "<<cnt<<" "<<t<<endl; if (!ret)//末尾没0 { if (sum-cnt>=s1-1) ans+=1;//如果总数减去末尾1的数量任在[s1-1, s2]内,直接加1 else //因为进位会多出一个1,所以是s1-1 { int p=s1-(sum-cnt);//否则一位一位的补1 if (p==1) ans=d+1; else { ans=ans+1; p--; while (p--) { ans=ans+(1<<p); } } } } else//如果末尾有0 { if (sum<s2)//总1数小于s2 { ans=ans+1; } else//总1数等于s2 { int g=ret; while (g--)//把末尾的1变成1 ans=ans+(1<<g); ans+=1; int p=sum-cnt+1; if (p<s1)//如果1的个数还小于s1,那就又变成的末尾没1的情况了 { int h=s1-p; while (h--) { ans=ans+(1<<h); } } } } printf ("%I64d\n",ans); } return 0; }
相关文章推荐
- opencv7-ml之KNN
- visual studio 静态库项目
- PHP数组 与 JSON 互相转换 (json_encode和json_decode的使用)
- POJ 3624 Charm Bracelet 【0 1背包】
- STL 清除模板容器 clear.h
- Java 大数值
- [ruby][文件操作]对当前文件夹下的文件进行重命名
- 顺序表(ArrayList)java实现
- epoll简介(二)
- JavaScript高级程序设计之面向对象的程序设计之继承之原型链 第6.3.1讲笔记
- 封装的概念和原理,set和get方法
- Maven-配置链接到私服及设置本地仓库
- 浅谈关于Java的注解使用
- 读懂程序里的--时间
- 逻辑和情绪
- OpenStack OVS GRE/VXLAN网络
- Java Web开发1___JSP指令元素:taglib指令
- HDU 5486 Difference of Clustering 图论
- LevelHostControl.xaml
- JSP的基础语法