题解:P13253 Part Elf
发表于更新于
字数总计:458阅读时长:1分钟 JohnCh's Home
题解洛谷题解:P13253 Part Elf
John Chiao形式化题意
给定一个分数 $\frac{P}{Q}$,它是由若干个分数的平均值构成的。构造一个数列,其中每个数要么为 $1$(即 $\frac11$),要么为 $0$(即 $\frac00$),输出至少经过几次平均运算才能从这样的数列构造出 $\frac{P}{Q}$。
(注:因为 $\frac{P}{Q}$ 是由平均值得来的,所以 $0 \le \frac{P}{Q} \le 1$。)
示例
分数为 $\frac14$,可以由下式得出:
$$
\large{\frac{\frac{0}{1}+\frac{1}{2}}{2}}
$$
思路
由于目标分数是由多次平均值得出的,分母只通过通分运算和乘以 $\frac12$ 的运算改变,因此可以证明:有效的目标分数分母一定为 $2$ 的幂次。
如果分母不为 $2$ 的幂次,直接判否,输出 impossible。
同样可以证明:约分后的分子 $\frac{P}{\gcd(P,Q)}$ 为奇数(即不含因数 $2$)。
可以将这个题目想象为一棵二叉树,底部的每一对节点对目标分数的贡献相当于 $\log_2 n$。要得到分子 $P$,在每一层(作为叶子)需要的 $1$ 和 $0$ 的数量是恒定的,只需找到可以容纳这些数的最低层数 $k$ 即可。
代码
:::success[AC Code]
line-numbers1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| #include<bits/stdc++.h> #define int long long
using namespace std;
signed main() { int T; cin >> T; for (int i = 1; i <= T; i++) { int p, q; char _; cin >> p >> _ >> q; cout << "Case #" << i << ": "; int g = __gcd(p, q); p /= g; q /= g; int q1 = q; int j = 0; while (q1 % 2 == 0) { q1 /= 2; j++; } if (q1 != 1) { cout << "impossible" << endl; continue; } int ans = INT_MIN; for (int k = 1; k <= 40; k++) if (p * (1ll << k) >= q) { ans = k; break; } if (ans != INT_MIN) cout << ans << endl; else cout << "impossible"<<endl; } return 0; }
|
:::