Codeforces Round #529 (Div. 3) C. Powers Of Two(数学????)
•题意
给出一个整数 n ,问能否将 n 分解成 k 个数之和,且这 k 个数必须是 2 的幂。
如果可以,输出"YES",并打印出任意一组解,反之输出"NO";
•题解
预备知识补充:如何求出数 num 最少需要多少个 2的幂之和?
例如 :
num = 3 = 20+21至少需要两个
num = 4 = 22 至少需要一个
num = 17 = 24+20 至少需要两个
根据贪心的思想 :
令 2x ≤ num,求出最大的 x ,那么此时num可以表示为 num = 2x+num1 ( num1 = num-2x );
num1接着重复上述过程,求出 ≤num1 的最近的2x1,num1 = 2x1+num2 ( num2 = num1-2x1 );
那么num最少的2的幂之和就为 : 2x+2x1+2x2+.......;
如何求出x,x1,x2,......呢?
2x : ≤ num 的距num最近的2的幂
2x1 : ≤ num1 的距num1最近的2的幂
2x2 : ≤ num2 的距num2最近的2的幂
2x3 : ≤ num3 的距num3最近的2的幂
易得 :
(1) : num / 2x = oddNum , num / 2x1 = oddNum , num / 2x2 = oddNum ,......
(2) : num / a = evenNum , num / b = evenNum , num / c = evenNum ,........
(1)证明 :
num / 2x = 1;
num1 / 2x1 = 1 → (num-2x) / 2x1 = 1 → num / 2x1 - 2x / 2x1 = num / 2x1 - 2x-x1 = 1 → num / 2x1 = 1 + 2x-x1 = oddNum ( 奇+偶 );
num2 / 2x2 = 1 → (num-2x-2x1) / 2x2 = 1 → num / 2x1 - 2x / 2x2- 2x1 / 2x2 = 1 → num / 2x1 = 1 + 2x-x2+2x1-x2 = oddNum ( 奇+偶+偶 );
.................
(2)证明 :
num / a = (num1+2x) / a = num1 / a + 2x / a = 0+偶 = evenNum;( 2x1 ≤ num1 < a )
..................
所以说:
for i: to k
if(num/(^i)为奇数)
那么2^i就为num最少需要的2的幂之和的成员之一并且,$2^i$ 等价于 两个 $2^{i-1}$,所以,可以通过 $2^i$ 转化为 $2^{i-1}$ 开填充;
•Code
#include<iostream>
#include<cstdio>
using namespace std; int n,k;
int e[];//e[i] : num需要e[i]个2^i void Solve()
{
int curK=;
for(int i=;(<<i) <= n;++i)
if(n>>i&)
{
e[i]=;
curK++;
}
//最少需要curK个2的幂
if(k < curK || k > n)
{
printf("NO\n");
return ;
}
printf("YES\n");
for(int i=;~i;--i)
{
if(!e[i])
continue;
if(curK == k)
break;
int x=min(e[i],k-curK);
e[i] -= x;//减少x个2^i
e[i-] += *x;//增加2*x个2^(i-1)
curK += x;//比之前多了x个
}
for(int i=;i <= ;++i)
for(int j=;j < e[i];++j)
printf("%d ",<<i);
}
int main()
{
scanf("%d%d",&n,&k);
Solve();
return ;
}
•感悟
其实,在比赛时,并没有做出这道题,不过也有点小想法,还不成熟;
赛后看排名,无意间看到了hdu大神Claris的排名,然后,看了一下Claris的提交代码,哇,真简洁,
是我目前无法达到的。
大约花费了一个多小时的时间才理解了%%%%%%%%%%%%
分割线2019.5.23
重新温习了一下这道题;
假设 n 最少由 k 个2的幂组成:
n = 2x1 + 2x2 +.......+ 2xk;
那么 n / 2xi 为奇数;
今天重新想了一下这个,没有像之前那么繁琐的推公式,一想就想到;
如果 n / 2xi 为偶数,那么 2xi 可以变为 2xi+1 使得组成 n 这个幂值更大,那么,肯定比2xi所需的2的幂少,与假设矛盾;
再次分割2019.10.24
二进制思想;
十进制数 n 对应的二进制的第 i 位如果为 1,那么 $2^i$ 就是二进制转十进制 n 的组成部分;
那么,也即是说,n 对应的二进制有多少个 1,n 就至少需要多少个 2 的幂之和;
如果这些不够 k 个,那么就通过一个 $2^i$ 可以转化为两个 $2^{i-1}$ 的形式来增加幂之和的个数;
Codeforces Round #529 (Div. 3) C. Powers Of Two(数学????)的更多相关文章
- Codeforces Round #529 (Div. 3) C. Powers Of Two
http://codeforces.com/contest/1095/problem/C 题意:给n找出k个2的幂,加起来正好等于n.例如 9,4:9 = 1 + 2 + 2 + 4 思路:首先任何数 ...
- Codeforces Round #529 (Div. 3) C. Powers Of Two (二进制)
题意:给你一个数\(n\),问是否能有\(k\)个\(2\)次方的数构成,若满足,输出一种合法的情况. 题解:从高到低枚举二进制的每一位,求出\(n\)的二进制的\(1\)的位置放进优先队列中,因为\ ...
- # Codeforces Round #529(Div.3)个人题解
Codeforces Round #529(Div.3)个人题解 前言: 闲来无事补了前天的cf,想着最近刷题有点点怠惰,就直接一场cf一场cf的刷算了,以后的题解也都会以每场的形式写出来 A. Re ...
- Codeforces Round #529 (Div. 3) E. Almost Regular Bracket Sequence (思维)
Codeforces Round #529 (Div. 3) 题目传送门 题意: 给你由左右括号组成的字符串,问你有多少处括号翻转过来是合法的序列 思路: 这么考虑: 如果是左括号 1)整个序列左括号 ...
- Codeforces Round #368 (Div. 2) C. Pythagorean Triples(数学)
Pythagorean Triples 题目链接: http://codeforces.com/contest/707/problem/C Description Katya studies in a ...
- Codeforces Round #622 (Div. 2) B. Different Rules(数学)
Codeforces Round #622 (Div. 2) B. Different Rules 题意: 你在参加一个比赛,最终按两场分赛的排名之和排名,每场分赛中不存在名次并列,给出参赛人数 n ...
- Codeforces Round #284 (Div. 2)A B C 模拟 数学
A. Watching a movie time limit per test 1 second memory limit per test 256 megabytes input standard ...
- CodeForces Round #529 Div.3
http://codeforces.com/contest/1095 A. Repeating Cipher #include <bits/stdc++.h> using namespac ...
- Codeforces Round #529 (Div. 3) 题解
生病康复中,心情很不好,下午回苏州. 刷了一套题散散心,Div 3,全部是 1 A,感觉比以前慢了好多好多啊. 这几天也整理了一下自己要做的事情,工作上要努力... ... 晚上还是要认认真真背英语的 ...
随机推荐
- Python自动化运维ansible从入门到精通
1. 下载安装 在windows下安装ansible:
- ubuntu 完全卸载mysql
卸载 sudo apt-get --purge remove mysql-common -y sudo apt-get --purge remove mysql* -y sudo apt-get au ...
- SpringMVC中对多部件类型解析---文件(图片)上传
加入上传图片jar包 commons-io-2.4.jar commons-fileupload-1.3.jar 在页面form中提交enctype="multipart/form-data ...
- LODOP循环多任务 同模版只设置不同队列任务名
LODOP中从PRINT_INIT(或PRINT_INITA)到最后PRINT(或PREVIEW等),是一个任务,关于Lodop中一个任务,以及一个任务中可以包含哪些语句,详细可查看本博客另一篇博文: ...
- JQuery跳出each循环的方法(包含数组遍历)
0. 前言 也许我们通过 jquery 的循环方法进行数组遍历,但是当不符合条件时,怎么跳出当前循环?(即用each方法内,当不满足条件时想break跳出循环体,想continue继续执行下一个循环遍 ...
- 21JDBC_事务&JDBCTemplate
一.JDBC_事务 通过JDBC来操作银行转账的事务 1.API介绍 Connection接口中与事务有关的方法 void setAutoCommit(boolean autoCommit) ...
- JVM安全点操作与测试小记
JVM的安全点学习与代码测试 监控安全点(打印JVM停顿时间,不止GC,处理毛刺): -XX:+PrintGC -XX:+PrintGCApplicationStoppedTime 取消偏向锁: -X ...
- BZOJ5119 生成树计数(prufer+生成函数+分治FFT+多项式exp)
https://www.luogu.org/problemnew/solution/P4002 神树的题解写的很清楚了.稍微补充: 1.[x^i]ln(A(ax))=a^i[x^i]ln(A(x)), ...
- springboot 学习
参考:http://www.cnblogs.com/sam-uncle/p/8796212.html spring boot 系列之一:spring boot 入门 注意:main启动类和contro ...
- 基准对象object中的基础类型----字典 (六)
object有如下子类: CLASSES object basestring str unicode buffer bytearray classmethod complex dict enumera ...