C - 0689
基本信息
题目出处 | 2019 陕西省大学生程序设计竞赛 |
队伍通过率 | 15/111 (13.5%) |
题解
先假设字符串里只有 \(0\) 和 \(8\)。
如果我们要翻转区间 \([l, r]\),而 \(s_l = s_r\),那么翻转 \([l, r]\) 的结果和翻转 \([l + 1, r - 1]\) 的结果是一样的。因此我们只考虑满足 \(s_l \ne s_r\) 的区间 \([l, r]\)。
考虑两个区间 \([l_1, r_1]\) 和 \([l_2, r_2]\) 满足 \(r_1 < r_2\),翻转这两个区间的结果一定是不同的。这是因为如果翻转 \([l_1, r_1]\),则 \(s_{r_2}\) 将保持不变;而翻转 \([l_2, r_2]\) 会让 \(s_{r_2}\) 发生变化。同理,如果 \(l_1 < l_2\),翻转两个区间的结果也一定不同。
因此答案就是满足 \(s_l \ne s_r\) 的区间 \([l, r]\) 的数量。
把 \(6\) 和 \(9\) 加回来,解法仍然是一样的。答案就是左右端点不是 \(00\)、\(88\)、\(69\)、\(96\) 的区间数量。
这里有一个细节问题:满足上述条件的区间,翻转的结果一定和原字符串不同。但如果存在一个区间,翻转的结果和原字符串相同,最终答案还要再加上 \(1\)。这里我们进行分类讨论。
- 如果原字符串存在 \(0\) 和 \(8\),那么只要翻转这个长度为 \(1\) 的区间,仍然还是原字符串。
- 否则,如果原字符串里都是 \(6\),那么翻转任何一个区间都会把 \(6\) 变成 \(9\),不可能得到原字符串。原字符串都是 \(9\) 的情况同理。
- 剩下的情况就是原字符串由 \(6\) 和 \(9\) 组成。这样的字符串一定存在子串 \(69\) 或者 \(96\),翻转这个长度为 \(2\) 的区间,仍然还是原字符串。
复杂度 \(\mathcal{O}(n)\)。
参考代码
1 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 |
|