思路大概就是留一个空栈,用来消栈底,其他的每个栈放两个,如果其他栈都放满了就判断能不能放在其他栈的栈顶,具体而言就是看下一次出现栈底前栈顶是否出现偶数次,如果所有栈都是奇数就直接放预先留的空栈。感觉可以消完的,但是挂成了35pts
代码
#include <bits/stdc++.h>
using namespace std;
namespace my_ns19825734575 {
const int maxm = 2e6 + 5;
const int maxn = 305;
const int maxk = 1005;
int a[maxm];
int bt[maxn], tp[maxn];
bool lock[maxn];
struct Output {
int op, x;
Output(int o, int v) {
op = o;
x = v;
}
void print() {
if (op == 1) printf("1 %d\n", x);
else printf("2 1 %d\n", x);
}
};
void main() {
memset(tp, 0, sizeof(tp));
memset(bt, 0, sizeof(bt));
memset(lock, 0, sizeof(lock));
int n, m, K;
scanf("%d %d %d", &n, &m, &K);
for (int i = 1; i <= m; ++i) scanf("%d", a + i);
vector<Output> ans;
int sv = -1, sp = -1;
for (int id = 1; id <= m; ++id) {
int t = a[id];
if (sv == t) {
ans.push_back({1, sp});
sv = sp = -1;
goto nL;
}
for (int i = 2; i <= n; ++i) {
if (tp[i] == t) {
ans.push_back({1, i});
if (!lock[i]) tp[i] = 0;
goto nL;
}
if (tp[i] == 0 && bt[i] == t) {
ans.push_back({1, i});
bt[i] = 0;
goto nL;
}
if (bt[i] == t) {
ans.push_back({1, 1});
ans.push_back({2, i});
bt[i] = tp[i];
if (sp == i) {
tp[i] = sv;
sp = sv = -1;
lock[i] = false;
} else {
tp[i] = 0;
}
goto nL;
}
}
for (int i = 2; i <= n; ++i) {
if (bt[i] == 0 || tp[i] == 0) {
if (bt[i] == 0) bt[i] = t;
else tp[i] = t;
ans.push_back({1, i});
goto nL;
}
}
sv = t;
for (int i = 2; i <= n; ++i) {
int c = 0;
for (int p = id + 1; a[p] != t; ++p) {
if (a[p] == bt[i]) {
if (c % 2 == 1) break;
else {
sp = i;
lock[i] = true;
ans.push_back({1, i});
goto nL;
}
} else if (a[p] == tp[i]) c += 1;
}
}
sp = 1;
ans.push_back({1, 1});
nL:;
}
printf("%d\n", (int)ans.size());
for (int i = 0; i < ans.size(); ++i) ans[i].print();
}
}
int main() {
// FILE IO !
int T;
scanf("%d", &T);
for (int _ = 0; _ < T; ++_) my_ns19825734575::main();
return 0;
}