1 solutions
-
0
本题的目标为求得 在执行 次操作 1 和 次操作 2 后的最小值和最大值。
解题思路
(以下的 符号均为整数除法) 操作 1 相当于 ; 操作 2 相当于 。
引理
引理 1:, 为正整数。 证明:设 ,则 ,从而,故 ,故成立。
引理 2:, 为正整数。 证明:设 ,则 ,从而 ,故 。
解题
假设 ,且第 次操作为操作 2,那么 进行 次操作后的结果为
$$\begin{aligned} &(x\underbrace{/2/2/\cdots/2}_{k-1}+1)/2\underbrace{/2\cdots/2}_{n-k+1} \\ =&(x/2^{k-1}+1)/2^{n-k} \\ =&(x+2^{k-1})/2^{n+1} \end{aligned} $$可以看出,当 ,即最先执行操作 2 时结果最小;当 ,即最后执行操作 2 时结果最大。 同理,假设执行 次操作 2,分别为第 次,则最终结果为
因此,最先执行 次操作 2 时为最小值,最后执行 次操作 2 时为最大值。
代码
#include <iostream> int getMin(int x, int n, int m) { // x = 0 或 1 时死循环,跳出 while (m > 0 && x > 1) { m--; x = (x + 1) / 2; } // x = 0 时死循环,跳出 while (n > 0 && x > 0) { n--; x = x / 2; } return x; } int getMax(int x, int n, int m) { while (n > 0 && x > 0) { n--; x = x / 2; } while (m > 0 && x > 1) { m--; x = (x + 1) / 2; } return x; } void solve() { int x, n, m; std::cin >> x >> n >> m; std::cout << getMin(x, n, m) << " " << getMax(x, n, m) << std::endl; } int main() { int T = 100; while(T--) { solve(); } return 0; }
Information
- ID
- 29
- Time
- 1000ms
- Memory
- 512MiB
- Difficulty
- 2
- Tags
- # Submissions
- 5
- Accepted
- 2
- Uploaded By