题意 : 给出一个数 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 ( 模拟 && 思维 )的更多相关文章

  1. CodeForces 916B Jamie and Binary Sequence (changed after round) (贪心)

    题意:给定两个数字n,m,让你把数字 n 拆成一个长度为 m 的序列a1,a2,a3...am,并且∑2^ai = n,如果有多组,要求序列中最大的数最小,然后再相同就要求除了最大数字典序最大. 析: ...

  2. Codeforces 916B - Jamie and Binary Sequence (changed after round)

    思路: 先取出二进制的每一位,判断总个数是不是小于等于k,如果大于k则不能构成. 通过观察可以发现,每一位的一个可以转换成下一位的两个,因为要使最大位尽可能小,所以如果最大位的所有的个数都可以转换成下 ...

  3. Jamie and Binary Sequence (changed after round) - CodeForces 916B

    http://codeforces.com/problemset/problem/916/B 好尬啊... #include<cstdio> #include<algorithm&g ...

  4. Jamie and Binary Sequence (changed after round) CodeForces - 916B (贪心)

    链接 大意: 求将n划分为k个2的幂的和, 且最大幂最小,字典序尽量大 比较简单的贪心练习题, 但放在div2的B题感觉偏难了..... 先只考虑最大幂最小, 首先注意到直接按n的二进制划分即可得到最 ...

  5. 【Codeforces Round #457 (Div. 2) B】Jamie and Binary Sequence

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 把n分解成二进制的形式. n=2^a0+2^a1+...+2^a[q-1] 则固定就是长度为q的序列. 要想扩展为长为k的序列. 可 ...

  6. Codeforces Beta Round #13 C. Sequence (DP)

    题目大意 给一个数列,长度不超过 5000,每次可以将其中的一个数加 1 或者减 1,问,最少需要多少次操作,才能使得这个数列单调不降 数列中每个数为 -109-109 中的一个数 做法分析 先这样考 ...

  7. 模拟+思维 HDOJ 5319 Painter

    题目传送门 /* 题意:刷墙,斜45度刷红色或蓝色,相交的成绿色,每次刷的是连续的一段,知道最终结果,问最少刷几次 模拟+思维:模拟能做,网上有更巧妙地做法,只要前一个不是一样的必然要刷一次,保证是最 ...

  8. Codeforces Round #546 (Div. 2) D 贪心 + 思维

    https://codeforces.com/contest/1136/problem/D 贪心 + 思维 题意 你面前有一个队列,加上你有n个人(n<=3e5),有m(m<=个交换法则, ...

  9. SBX(Simulated binary crossover)模拟二进制交叉算子和DE(differential evolution)差分进化算子

    一起来学演化计算-SBX(Simulated binary crossover)模拟二进制交叉算子和DE(differential evolution)差分进化算子 觉得有用的话,欢迎一起讨论相互学习 ...

随机推荐

  1. 2019暑假第二周(hadoop在个人电脑上的搭建)

    一,Hadoop和NoSQL数据库的学习,大多需要Linux环境. 搭建Linux环境可以分为两种方式: (1)在电脑上安装双操作系统,即同时安装Linux和Windows操作系统,在电脑启动的时候, ...

  2. python2.7安装numpy、pandas、matplotlib库

    我装的是python2.7 然后pip的版本是18.1,最近使用pip install **安装包的时候总是会提示 You are using pip version 18.1, however ve ...

  3. 密码学 - MD5 - 生成|加密|解密|相关工具

    生成MD5 解密 工具 - findmyhash使用方法:-h 直接跟hash值 -f 指定hash文件 -g 通过google查找hash 加密方式识别工具 hash-identifier 支持识别 ...

  4. sourceInsight下标题栏显示文件完整路径

    用sourceInsight看代码方便,但是标题栏中不显示文件的完整路径,有时候就会很麻烦,做如下设置即可显示完整的路径 options -> preferences -> Display ...

  5. 【Go语言】map在goroutine通信中的使用问题

    简介 本篇文章的主要内容是解决go语言map在使用中遇到的两个问题,对于初学者是不可避免的坑 一.cannot assign to struct field 当map中存在struct类型的成员,如果 ...

  6. Docker中的Dockerfile命令详解FROM RUN COPY ADD ENTRYPOINT...

    Dockerfile指令 这些建议旨在帮助您创建高效且可维护的Dockerfile. FROM FROM指令的Dockerfile引用 尽可能使用当前的官方图像作为图像的基础.我们推荐Alpine图像 ...

  7. 【Linux 环境搭建】Ubuntu下安装tftp

    1.安装软件    sudo apt-get install tftp-hpa tftpd-hap xinetd 2.修改配置文件    sudo vim /etc/default/tftpd-hpa ...

  8. 数位dp相关

    经典的数位Dp是要求统计符合限制的数字的个数. 一般的形式是:求区间[n,m]满足限制f(1). f(2). f(3)等等的数字的数量是多少. 条件 f(i) 一般与数的大小无关,而与数的组成有关. ...

  9. tensorflow学习笔记三----------基本操作

    tensorflow中的一些操作和numpy中的很像,下面列出几个比较常见的操作 import tensorflow as tf #定义三行四列的零矩阵 tf.zeros([3,4]) #定义两行三列 ...

  10. 服务器上部署django项目流程?

    1. 简单粗暴 项目开发完毕,在部署之前需要再配置文件中将 ALLOWED_HOSTS配置设置为:当前服务器IP或*,如: ALLOWED_HOSTS = ["*",] 然后将源码 ...