Codeforces 916B Jamie and Binary Sequence ( 模拟 && 思维 )
题意 : 给出一个数 n ,要求你用 k 个二的幂来组成这个数,要求输出这 k 个二的幂的指数,如果有多解情况则优先输出最大指数最小的那一个且要求按字典序输出,不存在则输出 No
分析 :
先来说一个结论对于一个二的幂例如 2^n 我们可以将其拆成 2^(n-1) + 2^(n-1)
那么对于题目所给出的数 n 我们可以先将其拆成二进制形式,如果当前二进制表示法中 1 的个数已经超过 k 则应该是输出 No
也就是说无论怎么转化都不可能有用更少的二的幂的个数来表示这个数,只能更多,也就是利用上面一拆多的结论
那么接下来就是用上述结论去一位位拆,为了保证拆出来的是符合题目要求的,按如下方式拆
首先为了保证最大的二的幂指数尽量小,我们始终从最高位拆
但是为了不超过 k 这个限制,当 2*最高位的二的幂的数量已经大于当前需要补充的数时候
这时候我们无法使得最大的二的幂被拆掉,所以为了保证字典序最小,我们此时从最低位开始拆
举个例子来说就是假设当前 n = 1010 (这里是二进制表示)、k = 4
那么一开始 n = 2^3 + 2^1 还需要补充 2 个二的幂
那么从最高位开始拆,变成 n = 2^2 + 2^2 + 2^1
此时还差 1 个二的幂,不过这个时候不能去拆最大的二的幂
应该拆 2^1 才能保证字典序
最后 n = 2^2 + 2^2 + 2^0 + 2^0
#include<bits/stdc++.h>
#define LL long long
using namespace std;
;
int k, cnt, lowbit, idx, arr[maxn];
LL n;
int main(void)
{
lowbit = -;
scanf("%I64d %d", &n, &k);
while(n){/// 先把 n 拆成二进制数
){
cnt++;/// n 的二进制表示法中 1 的数量
arr[idx]++;/// 记录当前二进制 1 所代表到底是哪个幂,例如 arr[2] => 2^2
)
lowbit = idx;
}
n >>= ;
idx++;/// n 的二进制表示法中有效位长
}
lowbit = (idx-)-lowbit;/// 计算出 n 的二进制表示法中最低位的那个 1 是第几位
std::reverse(arr, arr+idx);
//----------Debug-------------------
// for(int i=0; i<idx; i++)
// printf("%d ", arr[i]);
// puts("");
// printf("%d %d\n", idx, lowbit);
//----------Debug-------------------
if(cnt > k){/// No 的情况
puts("No");
;
}
;; i++){///从最高位开始进行拆分操作
if(cnt == k) break;
if(k - cnt < arr[i]) break;
cnt += arr[i];
arr[i+] += arr[i]<<;
arr[i] = ;
lowbit = max(lowbit, i+);
}
//------------Wrong!!!-----------------------
// while(cnt != k){
// if(arr[lowbit] >= k - cnt){
// arr[lowbit] -= k-cnt;
// arr[lowbit+1] += (k-cnt)<<1;
// cnt = k;
// }else{
// arr[lowbit+1] += arr[lowbit]<<1;
// cnt += arr[lowbit];
// arr[lowbit] = 0;
// }
// lowbit += 1;
// }
//------------Wrong!!!-----------------------
while(cnt != k){///Greedy!!!
cnt++;
arr[lowbit]--;
arr[++lowbit] += ;
}
puts("Yes");
; i<=lowbit; i++){
while(arr[i]){
arr[i]--;
printf(-i);
}
}puts("");
;
}
Codeforces 916B Jamie and Binary Sequence ( 模拟 && 思维 )的更多相关文章
- CodeForces 916B Jamie and Binary Sequence (changed after round) (贪心)
题意:给定两个数字n,m,让你把数字 n 拆成一个长度为 m 的序列a1,a2,a3...am,并且∑2^ai = n,如果有多组,要求序列中最大的数最小,然后再相同就要求除了最大数字典序最大. 析: ...
- Codeforces 916B - Jamie and Binary Sequence (changed after round)
思路: 先取出二进制的每一位,判断总个数是不是小于等于k,如果大于k则不能构成. 通过观察可以发现,每一位的一个可以转换成下一位的两个,因为要使最大位尽可能小,所以如果最大位的所有的个数都可以转换成下 ...
- Jamie and Binary Sequence (changed after round) - CodeForces 916B
http://codeforces.com/problemset/problem/916/B 好尬啊... #include<cstdio> #include<algorithm&g ...
- Jamie and Binary Sequence (changed after round) CodeForces - 916B (贪心)
链接 大意: 求将n划分为k个2的幂的和, 且最大幂最小,字典序尽量大 比较简单的贪心练习题, 但放在div2的B题感觉偏难了..... 先只考虑最大幂最小, 首先注意到直接按n的二进制划分即可得到最 ...
- 【Codeforces Round #457 (Div. 2) B】Jamie and Binary Sequence
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 把n分解成二进制的形式. n=2^a0+2^a1+...+2^a[q-1] 则固定就是长度为q的序列. 要想扩展为长为k的序列. 可 ...
- Codeforces Beta Round #13 C. Sequence (DP)
题目大意 给一个数列,长度不超过 5000,每次可以将其中的一个数加 1 或者减 1,问,最少需要多少次操作,才能使得这个数列单调不降 数列中每个数为 -109-109 中的一个数 做法分析 先这样考 ...
- 模拟+思维 HDOJ 5319 Painter
题目传送门 /* 题意:刷墙,斜45度刷红色或蓝色,相交的成绿色,每次刷的是连续的一段,知道最终结果,问最少刷几次 模拟+思维:模拟能做,网上有更巧妙地做法,只要前一个不是一样的必然要刷一次,保证是最 ...
- Codeforces Round #546 (Div. 2) D 贪心 + 思维
https://codeforces.com/contest/1136/problem/D 贪心 + 思维 题意 你面前有一个队列,加上你有n个人(n<=3e5),有m(m<=个交换法则, ...
- SBX(Simulated binary crossover)模拟二进制交叉算子和DE(differential evolution)差分进化算子
一起来学演化计算-SBX(Simulated binary crossover)模拟二进制交叉算子和DE(differential evolution)差分进化算子 觉得有用的话,欢迎一起讨论相互学习 ...
随机推荐
- MySQL知识集合
1.Mysql体系架构 2.MySQL文件结构 (1)参数文件:启动MySQL实例的时候,指定一些初始化参数,比如缓冲池大小.数据库文件路径.用户名密码等 -my.cnf读取优 ...
- unity让碰撞只发生一次
碰撞发生在帧的开始,所以你可以检测到冲突,并在LateUpdate复位: private bool hasCollided = false; void OnCollisionEnter(Collisi ...
- 应用安全 - Web框架 - Apache Solr - 漏洞汇总
CVE-2019-12409 Date: // 类型: 配置不当导致远程代码执行 前置条件: 影响范围: Solr and for Linux Solr下载:https://www.apache.or ...
- 只需要2个工具,百度云盘大文件就能用迅雷和IDM下载
不会代码,不懂脚本,没关系 ,能找到一座通往它们的桥梁,照样能到达彼岸. 这里以360极速浏览器为例. 在浏览器地址框输入以下地址直接到达浏览器安装扩展插件的地方(偷个懒,复制网址吧),https:/ ...
- linux 系统目录权限
小结: 目录的读.写.执行权限 1. 可读r:表示具有浏览目录 下面文件及子目录的权限 ls dir 1)如果没有x权限,则不能进到目录,既无法执行cd dir 2)如果没有x权限,ls列表时可以看到 ...
- Python解释器判断整数相加溢出
溢出,则和的最高位(即符号位)与两个加数都不相同,例如 1)非负数+非负数=负数 2)负数+负数=非负数 那么,假设x为a与b的和,((a^b)>=0 && (x^a)<0 ...
- Keil共存的方法 - Keil MDK兼容Keil C51,实操可行
记录一下成功使Keil MDK和Keil C51共存的过程! 之前一直用Keil C51开发,最近需要用到ARM9内核的IC,就需要Keil C51和Keil MDK共存.看了一下网上几个教程,方法大 ...
- [Web 前端] 023 js 的流程控制、循环和元素的获取、操作
1. Javascript 流程控制 用于"基于不同条件执行不同的动作"的场合 1.1 if 语句 三种形式 // 第一种 if... // 第二种 if... else ... ...
- [19/10/13-星期日] Python中的函数
一.函数 # 第五章 函数 ## 函数简介(function) - 函数也是一个对象 - 对象是内存中专门用来存储数据的一块区域 - 函数可以用来保存一些可执行的代码,并且可以在需要时,对这些语句进行 ...
- Zookeeper — 应用场景
大致来说,zookeeper 的使用场景如下,我就举几个简单的,大家能说几个就好了: 分布式协调 分布式锁 元数据/配置信息管理 HA高可用性 分布式协调 这个其实是 zookeeper 很经典的一个 ...