#优秀的拆分
前置知识:位运算。
#题面
#题目描述
一般来说,一个正整数可以拆分成若干个正整数的和。
例如,, 等。对于正整数 的一种特定拆分,我们称它为"优秀的",当且仅当在这种拆分下, 被分解为了若干个不同的 的正整数次幂。注意,一个数 能被表示成 的正整数次幂,当且仅当 能通过正整数个 相乘在一起得到。
例如, 是一个优秀的拆分。但是, 就不是一个优秀的拆分,因为 不是 的正整数次幂。
现在,给定正整数 ,你需要判断这个数的所有拆分中,是否存在优秀的拆分。若存在,请你给出具体的拆分方案。
#输入格式
输入只有一行,一个整数 ,代表需要判断的数。
#输出格式
如果这个数的所有拆分中,存在优秀的拆分。那么,你需要从大到小输出这个拆分中的每一个数,相邻两个数之间用一个空格隔开。可以证明,在规定了拆分数字的顺序后,该拆分方案是唯一的。
若不存在优秀的拆分,输出 -1
。
#思路
首先,如果 是奇数,那么肯定不可能拆分成若干个不同的 的正整数次幂。 以 的拆分结果 为例,可以看到结果里面存在一个 的 次幂。 所以当 是奇数时不存在优秀的拆分,输出 即可。
1 |
|
将 左移 位(1<<n
)和 是等效的。同理,将 右移 位(1>>n
)等同于 。取 的二进制第 位可以写成 x >> i & 1
。
我们观察一下 转换成二进制后的结果:,再将它转换成十进制的式子列出来:
再看下数据范围,24 次幂就足够了。
1 |
|
#代码
1 |
|
#直播获奖
#题面
#题目描述
NOI2130 即将举行。为了增加观赏性,CCF 决定逐一评出每个选手的成绩,并直播即时的获奖分数线。本次竞赛的获奖率为 ,即当前排名前 的选手的最低成绩就是即时的分数线。
更具体地,若当前已评出了 个选手的成绩,则当前计划获奖人数为 ,其中 是获奖百分比, 表示对 向下取整, 表示 和 中较大的数。如有选手成绩相同,则所有成绩并列的选手都能获奖,因此实际获奖人数可能比计划中多。
作为评测组的技术人员,请你帮 CCF 写一个直播程序。
#输入输出格式
#输入格式
第一行有两个整数 。分别代表选手总数与获奖率。 第二行有 个整数,依次代表逐一评出的选手成绩。
#输出格式
只有一行,包含 个非负整数,依次代表选手成绩逐一评出后,即时的获奖分数线。相邻两个整数间用一个空格分隔。
#思路
每读入一个数,使用二分插入到 vector 中,然后按照题意输出即可。
注意: 数组内成绩是由小到大排列的,所以输出的时候要使用 score.size() - max(1, i * w / 100)
作为下标。
#代码
1 |
|
#方格取数
#题面
#题目描述
设有 的方格图,每个方格中都有一个整数。现有一只小熊,想从图的左上角走到右下角,每一步只能向上、向下或向右走一格,并且不能重复经过已经走过的方格,也不能走出边界。小熊会取走所有经过的方格中的整数,求它能取到的整数之和的最大值。
#输入输出格式
#输入格式
第一行有两个整数 。
接下来 行每行 个整数,依次代表每个方格中的整数。
#输出格式
一个整数,表示小熊能取到的整数之和的最大值。
#思路
设 表示从一个格子上方走到该格子的路径最大和, 表示从一个格子下方走到该格子的路径最大和。
若搜到以前搜过的状态则直接返回搜过的最大和(也就是 中的值),否则继续搜索到达该格时的最大和。
#代码
1 |
|