# csu 1982:小M的移动硬盘(双向链表)

## Description

1 u 表示把编号为u的文件放到最上面
2 u 表示把编号为u的文件放到最下面
3 u v 表示把编号为u的文件放到编号为v的文件的后面

## 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第一次用链表做题,用一个数组保存每个数字所在的地址就可以实现O（1）查找了，坑了我很久，我开始建了一个循环双链表,结果死活WA(好像问题是出在第二步移动操作了),然后我将尾指针弃之不用,每次都是插在尾指针前面,然后就AC了.
#include<iostream>
#include<cstdio>
#include<algorithm>
#include <string.h>
#include <math.h>
using namespace std;
const int N =300005;
typedef long long LL;
typedef struct LNode{
int data;
struct LNode *next,*pre;

r = new LNode;
tail = new LNode;
L->next = L->pre = L;
L = r;
int i= 1;
while(i<=n){
p = new LNode;
p->data = i;
id[i] = p;
i++;
r->next = p;
p->pre = r;
r = p;
}
r->next = tail;
tail->pre = r;
}

p->next = L->next;
L->next = p;
p->pre = L;
p->next->pre = p;
}

tail->pre->next = p;
p->pre = tail->pre;
p->next = tail;
tail->pre = p;
}

q->next->pre = p;
p->pre = q;
p->next = q->next;
q->next = p;
}
LNode *p = L->next;
while(p!=tail){
printf("%d ",p->data);
p = p->next;
}
}

int main()
{
int tcase;
scanf("%d",&tcase);
int n,m;
while(tcase--)
{

L = new LNode;
scanf("%d %d",&n,&m);
create(n,L,tail);
int op,u,v;
while(m--){
scanf("%d",&op);
if(op==1){
scanf("%d",&u);
if(L->next ==p) continue;
p->pre->next = p->next;
p->next->pre = p->pre;
}
if(op==2){
scanf("%d",&u);
if(p==tail) continue;
p->pre->next = p->next;
p->next->pre = p->pre;
TailInsert(tail,p);
//Travel(L);
}
if(op==3){
scanf("%d %d",&u,&v);
LinkList p = id[u],q = id[v];
if(p==q) continue;
p->pre->next = p->next;
p->next->pre = p->pre;
InsertUV(p,q);
}
}
Travel(L);
while(p!=tail){
q = p;
p=p->next;
delete q;
}
delete tail;
printf("\n");
}

return 0;
}

posted @ 2017-08-29 16:42  樱花庄的龙之介大人  阅读(187)  评论(0编辑  收藏