| 记录编号 |
581796 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
| 题目名称 |
3812.[NOIP 2022] 喵了个喵 |
最终得分 |
100 |
| 用户昵称 |
┭┮﹏┭┮ |
是否通过 |
通过 |
| 代码语言 |
C++ |
运行时间 |
5.826 s |
| 提交时间 |
2023-08-13 19:42:38 |
内存使用 |
11.02 MiB |
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
const int N = 310,M = 2e6+10;
int T,n,m,k;
int a[M],id[2*N];//a为原数组 id为某类牌所在栈编号,没有则为0
struct made{
int v1,v2;
};
int stp;//辅助栈编号
deque<int>st[N];//每个栈
queue<int>q;//维护空栈
vector<made>ans;//答案
void first_() {
ans.clear();//清空答案
stp = n;//最开始辅助栈定为n
memset(id,0,sizeof(id));
}
void pu(int x,int y){
ans.push_back((made){x,y});
}
bool simple(int x){
int stx = id[x];
if(!stx){
if(q.empty())return false;
id[x] = stx = q.front();
q.pop();
pu(stx,0);
st[stx].push_back(x);
}
else{
id[x] = 0;
q.push(stx);
if(st[stx].back() == x){
pu(stx,0);
st[stx].pop_back();
}
else{
pu(stp,0);//首先放到辅助栈里
pu(stx,stp);
st[stx].pop_front();
}
}
return true;
}
int main(){
freopen("meow.in","r",stdin);
freopen("meow.out","w",stdout);
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&m,&k);//n个栈 m个卡牌 k种卡牌
first_();
for(int i = 1;i <= m;i++)
scanf("%d",&a[i]);//离线操作
while(!q.empty())q.pop();
for(int i = 1;i < n;i++){q.push(i);q.push(i);}
for(int i = 1;i <= m;i++){
if(!simple(a[i])){
int now = a[i],nx = i+1;int x = a[nx];
for(;nx <= m && x != now && x == st[id[x]].back();nx++,x = a[nx]);
//此时 nx 是 i 后第一个不在栈顶上的下标,x 是 a[nx]
if(x == now){
pu(stp,0);
for(int j = i+1;j < nx;j++)simple(a[j]);
pu(stp,0);
}
else{
int stx = id[x];int y = st[stx].back();
bool flag = true;//判断奇偶数
for(int j = i+1;j < nx;j++)
if(a[j] == y)flag = !flag;
if(flag){//偶数
pu(stx,0);
st[stx].push_back(a[i]);
for(int j = i+1;j < nx;j++){
if(a[j] == y)pu(stp,0);
else simple(a[j]);
}
pu(stp,0);pu(stx,stp);
st[stx].pop_front();
id[x] = 0;id[now] = stx;
}
else{//奇数
pu(stp,0);
st[stp].push_back(now);
for(int j = i+1;j < nx;j++){
if(a[j] == y)pu(stx,0);
else simple(a[j]);
}
pu(stx,0);
st[stx].clear();
//清空当前栈
id[x] = id[y] = 0;
id[now] = stp;
q.push(stp);
stp = stx;
}
}
i = nx;//因为循环内i会自动++,所以只需要赋值为r,自动r+1
}
}
printf("%d\n",ans.size());
for(int i = 0;i < ans.size();i++){
if(ans[i].v2)printf("2 %d %d\n",ans[i].v1,ans[i].v2);
else printf("1 %d\n",ans[i].v1);
}
}
return 0;
}