P8431 「WHOI-2」彗星蜜月 题解

· · 题解

前言

这题真的恶心,赛时写挂了就拿了 10 pts.

正文

Subtask # 1

考虑做 f_i 的前缀最大,则遇到第一个大于 Nf_i 即可知答案为 i - 1.

复杂度 \mathcal{O}(TN^2), 能拿个 10 分。

Subtask # 2

考虑到 f_i 的前缀最大序列具有单调性,可以二分查找,复杂度为 \mathcal{O}(TN \log_2 N), 能拿个 40 分。

Subtask # 3 - # 4

嘿嘿,既然直接暴力会死,不妨考虑找规律。

比如 9930843 对应 1000498, 40032 对应 10004, 99995 对应 69998.

如果你还看不出规律,那就再找找。

大量数据证明以下结论:

(第几位都是从左到右, len 为该数字的总位数, a_i 表示该数字的第 i 位上的数)

1. 对于以连续的 9 开头的

pos 为第一个非 9 的数字的位置,那么答案即为:

一个 1, len - pos - 10, 一个 a_{pos} + 1, pos - 29 和一个 8.

证明:

翻转后的第一位必为 1, 否则一定包括了不合法情况。

有一个 $a_{pos} + 1$ 是因为可以加上去,所以不加白不加就直接加。 $pos - 2$ 个 $9$ 是对应 $pos$ 之前的几个非首位 $9$. 注意:最后一个 $8$ 其实是 $9 - 1$. 这是因为前面在现在的高位(原来的低位)上大赚,这里(现在的低位,原来的高位)会小赔,不得不减去 $1$. --- 该死,还有一种情况: 注意有可能出现最后一位之前都是 $9$ 的情况,需要特判。 既然前面的 $0$ 都没了,自然首位可以取代一个 $a_{pos} + 1$. 于是答案就是一个 $a_{pos} + 1$, 一堆 $9$, 最后输出一个 $8$. ### 2. 对于不以连续的 $9$ 开头的 这个就简单了,还是按照第一种的相同的思路思考,可以发现答案为: 一个 $1$, 一堆 $0$, 末尾输出原数首位。 证明留给读者思考,这里不在赘述啦。 ### 3. 以零结尾 这个更简单,只需要减一即可。 证明: 以零结尾的数字翻转过来就一定比别人小了,那么前缀最大自然是上一个数的,而不可能是他的。 所以可以等效成求上一个数的答案。 --- 至此,分类讨论结束。题目解法出来了。 复杂度 $\mathcal{O}(\sum{\log_{10} N})$, 十分优秀可以通过。 # 代码 ``` cpp #include <bits/stdc++.h> #define ull unsigned long long using namespace std; ull T, N; signed main() { cin >> T; for(ull i = 1; i <= T; ++ i) { cin >> N; bool is_all_nine = true; ull cnt = 0, tmp[25]; memset(tmp, 0, sizeof(tmp)); ull tmpN = N; if(N <= 8) { cout << N << endl; continue; } if(N % 10 == 0) -- N, -- tmpN; while(N) { tmp[++ cnt] = N % 10; N /= 10; if(tmp[cnt] != 9) is_all_nine = false; } if(is_all_nine) cout << tmpN + 1 << endl; else { if(tmp[cnt] == 9) { ull T, pos = 0; for(ull i = cnt; i >= 1; -- i) { if(tmp[i] != 9) { T = tmp[i]; pos = i; break; } } if(pos == 1) { printf("%d", T + 1); for(ull i = 1; i <= cnt - 2; ++ i) putchar('9'); puts("8"); continue; } putchar('1'); for(ull i = 1; i <= pos - 2; ++ i) putchar('0'); putchar('0' + T + 1); for(ull i = 1; i <= cnt - pos - 1; ++ i) putchar('9'); puts("8"); } else { cout << 1; for(ull i = 1; i <= cnt - 2; ++ i) cout << 0; cout << tmp[cnt] << endl; } } } return 0; } ``` # 后言 就离谱,绿题也这么难...