喵了个喵 NOIP2022
喵了个喵 NOIP2022
WZH[NOIP2022] 喵了个喵
zhennanxie
题目链接: [NOIP2022] 喵了个喵 。
题目描述:
有 个栈,长度为 的序列 ,满足 。
有两种操作:
1 x。取出序列第一个元素并置于栈 的栈顶。若栈 的栈顶拥有两个相同元素,则删去他们。2 x y。若栈 和 的栈底元素一样,则删去他们。请合理构造使得最终序列和所有栈均为空。
数据保证有解。
数据范围(多测):
- 。
- 。
- 。
Case #1:
置空一个栈,其余栈最多每个有 个元素。
容易发现极限情况是所有可使用的栈全部被沾满,此时由于我空出了一个栈,所以所有元素都可以被消去。
简单模拟就行。
Case #2:
注意到如下两个构造:
1 | 栈1 栈2 |
1 | 栈1 栈2 |
不妨将他们命名为 c1 和 c2 。
先考虑 c2 。
此时若下一个元素是 或 则是平凡的。
若下一个是 ,不妨设下下个为 。
- 平凡。
- 将 置于栈 的栈顶,然后由于有了一个空栈,所以我们可以利用 把栈底的 消掉。此时又变回了 c2 。
- 将 置于栈 ,然后利用 把栈 的栈顶的 消掉,这样就回到了 c1 。
再考虑 c1 。
依旧考虑下一个元素为 ,下下个为 。
- 平凡。
- 将 置于栈 的栈顶,然后消掉 。此时回到 c2 。
- 同理回到 c2 。
因此我们发现这两种情况总能互通,其余情况是平凡的。
于是我们解决了。
Case #3: nothing
此时我们考虑效仿 和 的构造,不难得出这样两个情况:
1 | 栈1 栈2 栈3 栈4 栈5 ... |
1 | 栈1 栈2 栈3 栈4 栈5 ... |
仍然命名为 c1 和 c2 。
不难发现 c2 仍然可以转化为 c1 。
而 c1 ……并不能转回 c2 。
考虑这样的情况:
1 | 栈1 栈2 栈3 |
然后我们发现,只要下一个元素是 我们就会炸掉。
因此我们不能让 c2 变为 c1 。
考虑什么情况下 c2 会变为 c1 。
由于 c2 覆盖了 个不同的元素,因此不妨把剩下的那个记为 。序列的下一个元素为 ,下下个为 。
不难发现,当且仅当 为栈顶的时候, c2 会变为 c1 。
因此我们要避免这种情况。
注意到情况发生转换仅仅只是因为我把 放到了那一个空着的栈上。所以我不能把 放到空栈上。
又因为如果随便把 放到某一个栈的栈顶,那么那一个栈将会有 个元素,中间的元素不好处理。
除非那一个栈的栈底被削掉了。
于是我们 All in all ,当 为栈顶时,我们应该不断的将 变为下一个序列的元素,直到 变为某一个栈的栈底时结束,然后我们就可以把 放到那个栈上,将途中所有的序列元素直接进行消除即可。
细节真多。
代码:
1 |
|

