[NOIP2022] 喵了个喵 题解
[NOIP2022] 喵了个喵 题解
先考虑,这个数字提示我们每个栈放两种颜色,剩下一个栈辅助操作。那么颜色被分为两类
- 在栈底,可以通过操作2消去。
- 在栈顶,可以通过操作1消去。
这样就做完了。
现在普通栈放满了,又来了一个颜色,容易想到,如果这个颜色到下一个颜色之间没有栈底颜色,那么实际上可以直接把这个颜色放在辅助栈里面消去。这是第一种情况。
接下来让我们考虑这个颜色到下一个颜色之间有栈底颜色的情况,按照一些基本套路,可以考虑第一个栈底颜色,那么中间这些颜色可以分为可以按第一种情况操作的和。
令新的颜色为,第一个栈底颜色为,对应的栈顶颜色为。
我们先来思考和中间这些颜色怎么放,其实只用考虑怎么放,因为剩下这些颜色可以直接用操作1干掉。
- 出现奇数次,直接把放在辅助栈,放在栈,那么在中间这些颜色放完后就没有了,那么接下来可以把也通过操作1消去。这时候原本在的这个栈就空出来了,那么可以把它变成新的辅助栈。
- 出现偶数次,这个时候我们就没办法把上面变成空的了。所以只能通过操作2消去,所以辅助栈一定要空出来,注意到其实可以直接把放在所在的栈的栈顶,同时把放在辅助栈,这样在辅助栈中的一定会被消去。最后就可以通过操作2把消掉,这时候辅助栈就又空出来了。
直接模拟上面几种情况,就可以构造出的合法方案了。
改完题发现这题并没有想象中这么难,想法还是比较自然的。可能是这类构造做的不多,导致比赛时慌了。
#include <cstdio> #include <iostream> #include <vector> #include <queue> #include <cstring> #define LL long long using namespace std;namespace io { const int SIZE = (1 << 21) + 1; char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55]; int f, qr; #define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++) inline void flush () { fwrite (obuf, 1, oS - obuf, stdout); oS = obuf; } inline void putcc (char x) { *oS ++ = x; if (oS == oT) flush (); } template <class I> inline void gi (I &x) { for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1; for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15); x *= f; } template <class I> inline void print (I x) { if (!x) putcc ('0'); if (x < 0) putcc ('-'), x = -x; while (x) qu[++ qr] = x % 10 + '0', x /= 10; while (qr) putcc (qu[qr --]); } } using namespace io; const int N = 610; const int S = 2e6 + 10; int n, m, k, a[S], tot; struct Move { int tp, x, y; Move(int TP, int X, int Y) : tp(TP), x(X), y(Y) {} }; vector<Move> ans; inline void move(int x) {ans.emplace_back(Move(1, x, 0));} inline void move(int x, int y) {ans.emplace_back(Move(2, x, y));} queue<int> nor; int sz[N], type[N]; int id, ins[N], top[N]; void insert(int x) { while(!nor.empty() && (sz[nor.front()] == 2 || nor.front() == id)) nor.pop(); int p = nor.front(); if(sz[p] == 0) type[x] = 1; else type[x] = 2, top[p] = x; ins[x] = p, ++sz[p], move(p), ++tot; } void match(int x) { nor.push(ins[x]); if(type[x] == 1) { move(id), move(id, ins[x]); --sz[ins[x]], type[top[ins[x]]] = 1, top[ins[x]] = 0; } else if(type[x] == 2){ move(ins[x]); --sz[ins[x]], top[ins[x]] = 0; } ins[x] = type[x] = 0; --tot; } int work(int l) { int r = l + 1; while(a[r] != a[l] && type[a[r]] == 2 && r <= m) ++r; if(a[r] == a[l]) { move(id); for(int i = l + 1; i < r; ++i) { if(ins[a[i]]) match(a[i]); else insert(a[i]); } move(id); } else { int parity = 0, y = a[r], st = ins[a[r]], z = top[st], x = a[l]; for(int i = l + 1; i < r; ++i) parity ^= (a[i] == z); if(parity) { move(id); for(int i = l + 1; i < r; ++i) { if(a[i] == z) move(st); else if(ins[a[i]]) match(a[i]); else insert(a[i]); } move(st); type[x] = 1, sz[id] = 1, ins[x] = id; type[y] = type[z] = 0, top[st] = 0, ins[y] = ins[z] = 0, sz[st] = 0; nor.push(id); --tot, id = st; } else { move(st); for(int i = l + 1; i < r; ++i) { if(a[i] == z) move(st); else if(ins[a[i]]) match(a[i]); else insert(a[i]); } move(id), move(id, st); top[st] = x; type[z] = 1, type[x] = 2, ins[x] = st; type[y] = 0, ins[y] = 0; } } return r; } void clear() { ans.clear(); memset(ins, 0, sizeof ins); memset(top, 0, sizeof top); memset(sz, 0, sizeof sz); memset(type, 0, sizeof type); while(!nor.empty()) nor.pop(); for(int i = 2; i <= n; ++i) nor.push(i); tot = 0, id = 1; } void out() { print(ans.size()), putcc('\n'); for(auto x : ans) { if(x.tp == 1) putcc('1'), putcc(' '), print(x.x); else putcc('2'), putcc(' '), print(x.x), putcc(' '), print(x.y); putcc('\n'); } return ; } void solve() { gi(n), gi(m), gi(k); clear(); for(int i = 1; i <= m; ++i) gi(a[i]); for(int i = 1; i <= m; ++i) { if(ins[a[i]]) match(a[i]); else if(tot < 2 * (n - 1)) insert(a[i]); else i = work(i); } out(); } int main() { freopen("meow.in","r",stdin); freopen("meow.out","w",stdout); int T = 0; gi(T); while(T--) solve(); flush(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现