作为一个渣渣
emmmm一直害怕用链表……
但是这道题很明显一直在移动,即不断地插入、删除,显然用链表是很方便的,正在纠结的时候,发现用数组模拟链表的操作也是可以滴,而且也没有很麻烦(开心.jpg)
先看题目:
题目意思很清楚不再过多解释,下面结合代码说明模拟过程。
#include<iostream>
#include<cstdio>
#define maxn 300005
using namespace std;
int r[maxn],l[maxn]; //r[i]表示i的右边是几号,l[i]表示i的左边是几号
void moves(int a,int b) //把a插到b的前面(上面)
{
r[a]=b;
l[b]=a;
}
int main(void)
{
int t,n,m;
int pos;
int dig,a,b;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
r[0]=1; //一开始是1号到n号从上往下排列,为了之后方便对第一个进行操作,把0的右边设为1
l[n+1]=n; //把n+1的左边设为n
for(int i=1;i<=n;i++)
{
r[i]=i+1;
l[i]=i-1;
}
for(int i=0;i<m;i++)
{
scanf("%d",&pos);
switch(pos)
{
case 1:
scanf("%d",&dig);
if(r[0]!=dig) //如果dig是第一个的话就不用操作了
{
moves(l[dig],r[dig]); //现在dig后面的(r[dig])在dig前面的(l[dig])后面了
moves(dig,r[0]); //dig在r[0]前面
moves(0,dig);//dig在0的后面
}
break;
case 2:
scanf("%d",&dig);
if(l[n+1]!=dig)
{
moves(l[dig],r[dig]);
moves(l[n+1],dig);
moves(dig,n+1);
}
break;
case 3:
scanf("%d%d",&a,&b);
if(r[b]!=a)
{
moves(l[a],r[a]);
moves(a,r[b]);
moves(b,a);
}
break;
}
}
//下面是输出
int mid=r[0];
printf("%d",r[0]);
while (r[mid]<(n+1))
{
printf(" %d",r[mid]);
mid=r[mid];
}
printf("\n");
}
return 0;
}
开心