SPOJ SORTBIT Sorted bit squence (数位DP,入门)
题意:
给出一个范围[m,n],按照二进制表示中的1的个数从小到大排序,若1的个数相同,则按照十进制大小排序。求排序后的第k个数。注意:m*n>=0。
思路:
也是看论文的。一开始也能想到是这种解法,枚举0~31个1,逐步缩小第k个数的范围(其实就是找到第k个数应该有几个1),然后二分答案,直到找到第k个数。
我只是在找第k个数时不是二分答案,而是想直接从最高位往低位走,判断左子树中满足条件的数的数量,然后控制往下一位应该是0还是1(即往树的哪一个孩子方向走,直到根)。其实也是二分思想。
这题明显只有两个范围:[-INF,0]或者[0,INF],要特别注意n=0或者m=0的情况,有可能第k个数就是0,否则,是不是0就没有什么影响了。
1 //#include <bits/stdc++.h> 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <map> 7 #include <algorithm> 8 #include <vector> 9 #include <iostream> 10 #define pii pair<int,int> 11 #define INF 0x7f3f3f3f 12 #define LL long long 13 using namespace std; 14 const double PI = acos(-1.0); 15 const int N=35; //注意大小 16 17 int f[N][N], bit[N], m, n, k;; 18 void pre_cal() //预处理组合数 19 { 20 f[0][0]=1; 21 for(int i=1; i<N; i++) //位数 22 { 23 f[i][0]=f[i][i]=1; 24 for(int j=1; j<i; j++) //多少个1 25 { 26 f[i][j]=f[i-1][j]+f[i-1][j-1]; 27 } 28 } 29 } 30 31 int cal(int n,int k,int b) 32 { 33 memset(bit, 0, sizeof(bit)); 34 int len=0, cnt=0, ans=0; 35 while(n) //转成b进制 36 { 37 bit[++len]=n%b; 38 n/=b; 39 } 40 for(int i=len; i>0; i--) 41 { 42 if( bit[i]==1 ) 43 { 44 ans+=f[i-1][k-cnt]; //统计左边的 45 if(++cnt>k) break; //已超 46 } 47 } 48 if(cnt==k) ans++; 49 return ans; 50 } 51 52 53 int get_ans(int m,int n,int k) 54 { 55 int i, num; 56 for(i=0; i<=31; i++) //枚举位数 57 { 58 num=cal(n,i,2)-cal(m-1,i,2); 59 if(k-num<=0) break; 60 else k-=num; 61 } 62 int L=m,R=n; 63 while( L<R ) //二分答案 64 { 65 int mid=R-(R-L+1)/2; 66 num=cal(mid,i,2)-cal(m-1,i,2); 67 if( num<k ) L=mid+1; 68 else R=mid; //如果等于,也是继续缩小范围的 69 } 70 return R; 71 } 72 73 74 int main() 75 { 76 //freopen("input.txt","r",stdin); 77 pre_cal(); 78 int t;cin>>t; 79 while(t--) 80 { 81 scanf("%d%d%d",&m,&n,&k); 82 if(m<0) 83 { 84 m^=(1<<31); //改为正 85 if(n==0) //上界为0 86 { 87 n--; 88 n^=(1<<31); 89 if(get_ans(m,n,k-1)==n) printf("0\n"); 90 else cout<<(get_ans(m,n,k)^(1<<31))<<endl; 91 } 92 else 93 { 94 n^=(1<<31); 95 cout<<(get_ans(m,n,k)^(1<<31))<<endl; //恢复负值 96 } 97 } 98 else 99 { 100 if(m==0&&k==1) {printf("0\n");continue;} 101 else if(m==0) m++,k--; 102 cout<<get_ans(m,n,k)<<endl; 103 } 104 } 105 return 0; 106 }
AC代码
转载于:https://www.cnblogs.com/xcw0754/p/4852036.html
SPOJ SORTBIT Sorted bit squence (数位DP,入门)相关推荐
- hdu 2089 数位dp入门
HDU 2089 题意:中文题 思路:数位dp入门题 AC代码: #include "iostream" #include "string.h" #includ ...
- 数位dp入门题 洛谷P2657 [SCOI2009] windy 数
题干 传送门 windy 定义了一种 windy 数. 题目描述 不含前导零且相邻两个数字之差至少为 2的正整数被称为 windy 数.windy 想知道,在 a 和 b 之间,包括 a 和 b ,总 ...
- 数位DP入门+数位DP模板
数位dp是一种计数用的dp,一般就是要统计一个区间[le,ri]内满足一些条件数的个数.所谓数位dp,字面意思就是在数位上进行dp咯.数位还算是比较好听的名字,数位的含义:一个数有个位.十位.百位.千 ...
- 数位 DP 入门 (不要 62+windy 数)
\[I\] 平常的做法是设 \(f_{i,j}\) 为 \(0\)~\(j \times 10^{i-1}\) 的合法个数,这里用某种神奇而快速的做法. 简化题意: 不要 \(6\ 2\) 连在一起的 ...
- 数位DP 学习笔记1(数位DP入门)
HDU 2089 不要62: 题目大意是给你一个区间,让你统计这个区间里不包含 4 和 62 的数字的个数. 最朴素的思路是: 对于每个区间 [l, r],遍历所有在区间 [l, r] 里的数字,然后 ...
- P2657 [SCOI2009]windy数 数位dp入门
参考了题解,理解仍然还不够透彻 #include<bits/stdc++.h> using namespace std; const int N=550; const int maxn=1 ...
- 牛客网 G-送分了 QAQ 数位 dp入门
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K 64bit IO Format: %lld 题目描述 链接: https://www.nowcode ...
- 数位DP入门笔记(1)HUD-2089
题目: 题目理解和思路: 1.此题是给一个6位车牌号,正着不能含有连着的62,不能有4. 2.判断车牌号可能会采用dfs,因为每增加一位数就包含带4,或者形成62两种不合法情况(可以用但此代码没有用到 ...
- 数位DP入门之hdu 3652 B-number
hdu 3652 B-number Problem Description A wqb-number, or B-number for short, is a non-negative integer ...
最新文章
- VueJs路由跳转——vue-router的使用
- 前端遍历导致查询数据时间过长_OLAP 服务器,空间换时间可行吗?
- 多值参数-定义及作用
- 运行第一个docker容器
- 上海应用技术学院c语言实验报告9,上海工程技术大学C语言实验报告
- 嘌呤含量高的食物大全
- linux 脚本使用第一篇
- 为全力发展AIOT,小米把松果电子分拆重组了
- 面试官问:Mybatis Plus 是如何实现动态 SQL 语句的?原理你懂吗?
- 利用【监听器】动态加载Log4j配置文件
- C++解析char *p与char p[]
- 简易语音助手—python
- 手把手教你用python写游戏
- 基于Matlab的人脸识别设计(PCA)
- python如何使用jieba库_Python jieba库的使用
- 使用讯飞tts实现安卓语音中文合成播报
- 双11为什么成了传统电商的流量批发市场?
- 部署大宗商品撮合交易平台,实现高效交易与资源信息对接
- UG NX1980一键安装正式版+安装说明(安装简单)
- Protect访问权限
热门文章
- note同步不及时 one_一辆理想ONE又“跪了”?理想官方紧急发文回应
- linux 账号密码 字段,详解Linux中的用户密码管理命令passwd和change
- 克隆安装oracle,Oracle 之 Cloning $oracle_home (克隆安装oracle软件)
- android版本如何修改时间,如何修改Android系统默认时间
- 卷积神经网络语音识别_用于物体识别的3D卷积神经网络
- java 继承示例_Java中的继承类型以及示例
- python如何操作oracle数据库_python操作oracle数据库
- 手动打开和关闭windows的相关服务
- UVA 11988——Broken Keyboard (a.k.a. Beiju Text)
- uva 10120——Gift?!