zoukankan      html  css  js  c++  java
  • csu 1982:小M的移动硬盘(双向链表)

    Description

    最近小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

    第一次用链表做题,用一个数组保存每个数字所在的地址就可以实现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("
    ");
        }
    
        return 0;
    }
  • 相关阅读:
    606. Construct String from Binary Tree
    696. Count Binary Substrings
    POJ 3255 Roadblocks (次短路)
    POJ 2823 Sliding Window (单调队列)
    POJ 1704 Georgia and Bob (博弈)
    UVa 1663 Purifying Machine (二分匹配)
    UVa 10801 Lift Hopping (Dijkstra)
    POJ 3281 Dining (网络流之最大流)
    UVa 11100 The Trip, 2007 (题意+贪心)
    UVaLive 4254 Processor (二分+优先队列)
  • 原文地址:https://www.cnblogs.com/liyinggang/p/7449048.html
Copyright © 2011-2022 走看看