Title:
最近小M买了一个移动硬盘来储存自己电脑里不常用的文件。但是他把这些文件一股脑丢进移动硬盘后,觉得这些文件似乎没有被很好地归类,这样以后找起来岂不是会非常麻烦?
小M最终决定要把这些文件好好归类,把同一类地移动到一起。所以现在小M有了这几种操作:
1 u 表示把编号为u的文件放到最上面
2 u 表示把编号为u的文件放到最下面
3 u v 表示把编号为u的文件放到编号为v的文件的后面
已知在最开始的时候,1号文件到n号文件从上往下排布
现在小M已经给出了他所进行的所有操作,你能告诉他操作之后的序列是会变成什么样子吗?
Input
第一行为一个数字T(T<=10)表示数据组数
第二行为两个数字n、m(1<=n,m<=300000)表示序列长度和小M的操作次数
接下来m行每行两个或三个数字,具体含义见题面
保证数据合法
Output
输出一行表示小M操作结束后的序列
Sample Input
1
10 5
1 5
2 3
2 6
3 4 8
3 1 3
Sample Output
5 2 7 8 4 9 10 3 1 6
思路:
链表或者数组模拟一下,(采用的是双向指针标记解决)。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string.h>
#include <algorithm>
#include <list>
#include <stdlib.h>
using namespace std;
int n,m;
int type,k;
int Left[300005],Right[300005];
int u,v;
void chushihua()
{
for(int i=1; i<=n+2; i++)
{
Left[i] = i-1;
Right[i] = i+1;
}
Right[0] = 1;
}
void print()
{
int temp = Right[0];
printf("%d",temp);
temp = Right[temp];
while( temp<= n )
{
printf(" %d",temp);
temp = Right[temp];
}
printf("\n");
}
void Updata(int x,int y)
{
Left[y] = x;
Right[x] = y;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
chushihua();
for(int i=1; i<=m; i++)
{
scanf("%d",&type);
if(type == 1){
scanf("%d",&k);
if(Left[0] == k)
continue;
Updata(Left[k],Right[k]);
Updata(k,Right[0]);
Updata(0,k);
}
else if(type == 2){
scanf("%d",&k);
///先独立出来
Updata(Left[k],Right[k]);
///将最后一个节点修改为k
Updata(Left[n+1],k);
///修改最后一个节点的信息
Updata(k,n+1);
}
else{
scanf("%d%d",&u,&v);
///先把u独立出来
Updata(Left[u],Right[u]);
///设置v的后面的前面是u
Updata(u,Right[v]);
///设置u的前面是v
Updata(v,u);
}
}
print();
}
return 0;
}
附超时的单项链表模拟代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string.h>
#include <algorithm>
#include <vector>
#include <stdlib.h>
using namespace std;
int n,m;
int type,k;
struct node
{
int data;
node *next;
}*ans,*start;
int u,v;
void chushihua()
{
ans = (struct node*)malloc(sizeof(struct node));
ans->data = -1;
ans->next =NULL;
start = (struct node*)malloc(sizeof(struct node));
start = ans;
for(int i=1;i<=n;i++){
struct node *code;
code = (struct node*)malloc(sizeof(struct node));
code->data = i;
code->next = NULL;
ans->next = code;
ans = ans->next;
}
}
void change(int sign,int data)
{
node *Now = ans,*flag;
if(sign == 1){
while(ans->next && ans->next->data != data)
ans = ans->next;
flag = ans->next;
///找到了,如果是第一个的话,那么我们就改变最后一个节点
if(ans->next->next == NULL)
{
ans->next = NULL;
flag->next = Now->next;
Now->next = flag;
}else{
ans->next = ans->next->next;
flag->next = Now->next;
Now->next = flag;
}
}else{
while(ans->next && ans->next->data != data)
ans = ans->next;
///找到了如果是最后一个的话,那么我们就改变最后一个节点
if(ans->next->next == NULL)
return ;
flag = ans->next;
ans->next = ans->next->next;
///找到最后面去
while(ans->next)
ans = ans->next;
ans->next = flag;
flag->next = NULL;
}
}
void updata(int u,int v)
{
node *pre_u,*flag_v;
///找到u的位置
while( ans->next && ans->next->data != u )
ans = ans->next;
pre_u = ans->next;
///修改表的内容
if(pre_u->next == NULL) ans->next = NULL;
else ans->next = pre_u->next;
///找到v的位置并且将flag_u放在他的后面
ans = start;
while( ans && ans->data != v )
ans = ans->next;
flag_v = ans->next;
pre_u->next = flag_v;
ans->next = pre_u;
return ;
}
void print()
{
node *Now = ans;
ans = ans->next;
printf("%d",ans->data);
ans = ans->next;
while(ans){
printf(" %d",ans->data);
ans = ans->next;
}
printf("\n");
}
void Free()
{
node *p;
while(ans!=NULL){
p = ans;
ans = ans->next;
free(p);
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
ans = start;
chushihua();
for(int i=1;i<=m;i++){
scanf("%d",&type);
if(type == 1 || type == 2){
ans = start;
scanf("%d",&k);
change(type,k);
}else{
ans = start;
scanf("%d%d",&u,&v);
updata(u,v);
}
}
ans = start;
print();
}
return 0;
}