调了一个多小时没调出来,怀疑策略有问题。
策略如下:
否则往后找第一个与当前元素相同或者在栈底的元素。
如果找到的是与当前元素相同的元素:
具体看代码(可读性应该还可以)。
这个策略对吗/kel,快破防了。
#include<bits/stdc++.h>
using namespace std;
deque<int> stk[305];
int t, n, m, k, pos, nxt, a[2000005], buk[2005], ins[2005];
set<int> siz[20];
struct operator_{
int op, u, v;
};
queue<operator_> operator__;
void gensiz(int u, int lsz){//更新一个栈的大小
if (siz[lsz].find(u) == siz[lsz].end())
exit(3256);
siz[lsz].erase(u);
siz[stk[u].size()].insert(u);
}
void print(int u){
cerr << u << "(" << stk[u].size() << "):";
if (stk[u].empty()){
cout << "\n";
return;
}
cerr << stk[u].front() << " " << stk[u].back() << "\n";
}
void printall(){
for (int i = 1; i <= n; i++)
print(i);
}
void stk_ins(int u, int x){
int lu = stk[u].size();
// cerr << "1 " << u << "\n";
operator__.push({1, u, 0});
stk[u].push_back(x);
ins[x] = u;
gensiz(u, lu);
}
void c_bottom(int u, int v){//底部消除
// cerr << "2 " << u << " " << v << "\n";
operator__.push({2, u, v});
if (stk[u].empty() || stk[v].empty())
exit(325609);
if (stk[u].front() != stk[v].front())
exit(3256090);
int lu = stk[u].size(), lv = stk[v].size();
ins[stk[u].front()] = -1;
stk[u].pop_front();
stk[v].pop_front();
gensiz(u, lu);
gensiz(v, lv);
}
void c_top(int u, bool op = 1){//顶部连续两张牌相同
if (stk[u].size() < 2)
exit(32560900);
int lu = stk[u].size();
int x = stk[u].back();
if (op)
ins[x] = -1;
stk[u].pop_back();
int y = stk[u].back();
stk[u].pop_back();
if (x != y)
exit(325609000);
gensiz(u, lu);
}
void op1_1(int x){
if (ins[x] == -1){
int ppos = *siz[0].begin();
stk_ins(ppos, x);
}else{
if (stk[ins[x]].back() == x){
stk_ins(ins[x], x);
c_top(ins[x]);
}else if (stk[ins[x]].front() == x){
int tins = ins[x];
int ppos = *siz[0].begin();
stk_ins(ppos, x);
c_bottom(ppos, tins);
}
}
}
void op1_2(int x){
// cerr << x << "\n";
if (ins[x] == -1){
int ppos = *siz[1].begin();
stk_ins(ppos, x);
}else{
if (stk[ins[x]].back() == x){
stk_ins(ins[x], x);
c_top(ins[x]);
}else if (stk[ins[x]].front() == x){
int tins = ins[x];
int ppos = *siz[0].begin();
stk_ins(ppos, x);
c_bottom(ppos, tins);
}
}
}
int op2(int pos, int x){
if (ins[x] == -1){
if (a[pos + 1] == x){//连续两张相同
int ppos = *siz[0].begin();
stk_ins(ppos, x);
stk_ins(ppos, x);
c_top(ppos);
return pos + 1;
}else{
int op = 0, id = 0;
for (int i = pos + 1; i <= m; i++){
if (a[i] == x){
id = i;
op = 1;
break;
}else if (stk[ins[a[i]]].front() == a[i]){
id = i;
op = 2;
break;
}
}
if (op == 1){
int ppos = *siz[0].begin();
stk_ins(ppos, x);
for (int i = pos + 1; i <= id; i++){
stk_ins(ins[a[i]], a[i]);
c_top(ins[a[i]]);
}
return id;
}else{
int cnt = 0;
for (int i = pos + 1; i < id; i++){
if (a[i] == stk[ins[a[id]]].back())
cnt++;
}
if (cnt & 1){
int ppos = *siz[0].begin();
stk_ins(ppos, x);
for (int i = pos + 1; i <= id; i++){
stk_ins(ins[a[i]], a[i]);
c_top(ins[a[i]]);
}
return id;
}else{
int ppos = ins[a[id]];
int ntop = stk[ins[a[id]]].back();
stk_ins(ppos, x);
for (int i = pos + 1; i < id; i++){
if (a[i] == ntop){
if (stk[ppos].back() == ntop){
stk_ins(ins[a[i]], a[i]);
c_top(ins[a[i]], 0);
}else
stk_ins(ppos, a[i]);
continue;
}
if (ins[a[i]] == -1)
stk_ins(ppos, a[i]);
else{
stk_ins(ins[a[i]], a[i]);
c_top(ins[a[i]]);
}
}
int ppos2 = *siz[0].begin(), tins = ins[a[id]];
stk_ins(ppos2, a[id]);
c_bottom(tins, ppos2);
return id;
}
}
}
}else{
if (stk[ins[x]].back() == x){//消除顶部
stk_ins(ins[x], x);
c_top(ins[x]);
}else{//消除底部
int tins = ins[x];
int ppos = *siz[0].begin();
stk_ins(ppos, x);
c_bottom(ppos, tins);
}
return pos;
}
}
int work(int pos){
if (siz[0].size() > 1)//两个空栈
op1_1(a[pos]);
else if (siz[0].size() == 1 && siz[1].size())//一个空栈和一个只有一个元素的栈
op1_2(a[pos]);
else//一个空栈
return op2(pos, a[pos]);
return 0;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> t;
while (t--){
cin >> n >> m >> k;
for (int i = 1; i <= k; i++)
buk[a[i]] = 0;
for (int i = 1; i <= 15; i++)
siz[i].clear();
for (int i = 1; i <= n; i++){
while (!stk[i].empty())
stk[i].pop_front();
siz[0].insert(i);
}
for (int i = 1; i <= m; i++){
cin >> a[i];
buk[a[i]]++;
ins[a[i]] = -1;
}
for (int i = 1; i <= m; i++){
int res = work(i);
if (res)
i = res;
cerr << i << "\n";
printall();
cerr << "\n";
}
cout << operator__.size() << "\n";
while (!operator__.empty()){
operator_ tmp = operator__.front();
operator__.pop();
if (tmp.op == 1)
cout << 1 << " " << tmp.u << "\n";
else
cout << 2 << " " << tmp.u << " " << tmp.v << "\n";
}
}
return 0;
}