csu 1982:小M的移動硬盤(雙向鏈表)

Description

最近小M買了一個移動硬盤來儲存本身電腦裏不經常使用的文件。可是他把這些文件一股腦丟進移動硬盤後,以爲這些文件彷佛沒有被很好地歸類,這樣之後找起來豈不是會很是麻煩?
小M最終決定要把這些文件好好歸類,把同一類地移動到一塊兒。因此如今小M有了這幾種操做:
1 u 表示把編號爲u的文件放到最上面
2 u 表示把編號爲u的文件放到最下面
3 u v 表示把編號爲u的文件放到編號爲v的文件的後面
已知在最開始的時候,1號文件到n號文件從上往下排布
如今小M已經給出了他所進行的全部操做,你能告訴他操做以後的序列是會變成什麼樣子嗎?ios

Input

第一行爲一個數字T(T<=10)表示數據組數
第二行爲兩個數字n、m(1<=n,m<=300000)表示序列長度和小M的操做次數
接下來m行每行兩個或三個數字,具體含義見題面
保證數據合法數組

Output

輸出一行表示小M操做結束後的序列spa

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;
}*LinkList,LNode;

LinkList id[N];
LinkList L,tail;
void create(int n,LinkList &L,LinkList &tail){
    LinkList p,r;
    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;
}

void HeadInsert(LinkList &L,LinkList &p){
    p->next = L->next;
    L->next = p;
    p->pre = L;
    p->next->pre = p;
}

void TailInsert(LinkList &tail,LinkList &p){
    tail->pre->next = p;
    p->pre = tail->pre;
    p->next = tail;
    tail->pre = p;
}

void InsertUV(LinkList &p,LinkList &q){
    q->next->pre = p;
    p->pre = q;
    p->next = q->next;
    q->next = p;
}
void Travel(LinkList L){
    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);
                LinkList p = id[u];
                if(L->next ==p) continue;
                p->pre->next = p->next;
                p->next->pre = p->pre;
                HeadInsert(L,p);
            }
            if(op==2){
                scanf("%d",&u);
                LinkList p = id[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);
        LinkList p=L,q;
        while(p!=tail){
            q = p;
            p=p->next;
            delete q;
        }
        delete tail;
        printf("\n");
    }

    return 0;
}
相關文章
相關標籤/搜索