1. 程式人生 > >HDU 4286 Data Handler (雙向連結串列)

HDU 4286 Data Handler (雙向連結串列)

                                                 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)


Problem Description   You are in charge of data in a company, so you are called "Data Handler". Different from the data in computer, the data you have are really in huge volume, and each data contains only one integer. All the data are placed in a line from left to right. There are two "hand" to handle the data, call hand "L" and hand "R". Every hand is between two adjacent data or at the end of the data line.
  In one day, the company gives you many commands to handle these data, so you should finish them one by one. At the beginning, there are N data, and hand "L" and "R" are in some positions. Each command is one the following formats:
  (1)MoveLeft L/R: it means that you should move the hand "L"/"R" left one data unit;


  (2)MoveRight L/R: it means that you should move the hand "L"/"R" right one data unit;



  (3)Insert L X: it means that you should insert the data that contains X at the right of the hand "L";



  (4)Insert R X: it means that you should insert the data that contains X at the left of the hand "R";



  (5)Delete L: it means that you should delete the one data at the right of the hand "L";



  (6)Delete R: it means that you should delete the one data at the left of the hand "R";



  (7)Reverse: it means that you should reverse all the data between hand "L" and hand "R".


  After finish all the commands, you should record all the data from left to right. So please do it.

Input   The first line contains an integer T(1<=T<=10), the number of test cases.
  Then T test cases follow. For each test case, the first line contains an integer N(1<=N<=500000), the number of data at the beginning. The second line contains N integers, means the integer in each data, from left to right. The third line contains two integers L and R (1<=L<=R<=N), the positions of hand "L" and hand "R". It means that hand "L" is at the left of the L-th data and hand "R" is at the right of the R-th data. The fourth line contains one integer M(1<=M<=500000), the number of commands. Then M lines follow, each line contains a command in the above format. All the integers in the data will in range [-10000,10000].
  It is guaranteed that there are always some data between hand "L" and "R", and if the hand is at the left/right end of the data line, it will not receive the command MoveLeft/MoveRight.
  Because of large input, please use scanf instead of cin.

Output   For each test case, output the integers in the data from left to right in one line, separated in a single space.
  Because of large output, please use printf instead of cout.
  

Sample Input 2 5 1 2 3 4 5 1 5 5 MoveLeft R Insert R 6 Reverse Delete R Insert L 7 5 6536 5207 2609 6604 -4046 1 3 5 Delete L Insert R -9221 Reverse Delete L MoveRight L
Sample Output 7 6 4 3 2 5 2609 5207 6604 -4046

題意:給你一段數字,一個左指標和一個右指標,然後有七種操作,操作n次後,從左至右依次輸出變化後的數字串。

七種操作都非常簡單易懂,但是資料很大,如果暴力模擬絕對超時。

這裡我把這一串數字串拆分成了三部分,在左指標左邊的作為一個棧,右指標右邊的作為一個棧(因為對這兩部分的操作只有從一邊進,從這一邊出)

兩個指標之間的做成一個雙向連結串列,方便拆分和刪除,以及最後的輸出遍歷。

難點在於顛倒操作,但這樣拆成三部分之後,每次不用真正顛倒,只用直接將一個標記flag++就好了,奇數時代表串是反的,偶數時代表串是正的,然後在進行其它操作時判斷flag的奇偶然後分別操作就好了。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h>
#include <algorithm>
#include <vector>
#include <map>
#define PI acos(-1.0)
#define M 1000005  //10^6
#define eps 1e-8
#define LL long long
#define moo 1000000007
#define INF -999999999
#define LL long long
using namespace std;
struct aaa
{
    int val;
    int le;
    int ri; 
}aa[M];     //雙向連結串列
int stle[M];//左棧
int stri[M];//右棧
int b[M];   //初始讀入陣列
char a[10];
char d[10];
int judge()
{
    if(strcmp(a,"MoveLeft")==0)
        return 1;
    if(strcmp(a,"MoveRight")==0)
        return 2;
    if(strcmp(a,"Insert")==0)
        return 3;
    if(strcmp(a,"Delete")==0)
        return 4;
    if(strcmp(a,"Reverse")==0)
        return 5;
}
int main()
{
    int m,n,T;
    while(scanf("%d",&T)!=EOF)
    {
        while(T--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&b[i]);
            }
            int lee,rii;
            scanf("%d%d",&lee,&rii);
            int hele=0,heri=0;
            for(int i=1;i<lee;i++)
            {
                hele++;
                stle[hele]=b[i];
            }
            for(int i=n;i>rii;i--)
            {
                heri++;
                stri[heri]=b[i];
            }
            int now=rii-lee;
            for(int i=lee;i<=rii;i++)
            {
                aa[i-lee].le=i-lee-1;
                aa[i-lee].ri=(i==rii?-1:i-lee+1);
                aa[i-lee].val=b[i];
            }
            rii=rii-lee;
            lee=0;
            
            //以上是把三部分分別儲存好的操作。
            
            scanf("%d",&m);
            int flag=0;
            while(m--)
            {
                scanf("%s",a);
                int tt=judge();
                if(tt==5)
                {
                    flag++;
                    continue;
                }
                if(tt==1)
                {
                    scanf("%s",d);
                    if(strcmp(d,"L")==0)
                    {
                        aa[++now].val=stle[hele--];
                        if(flag%2==0)
                        {
                            aa[now].le=-1;
                            aa[lee].le=now;
                            aa[now].ri=lee;
                            lee=now;
                        }
                        else
                        {
                            aa[now].ri=-1;
                            aa[rii].ri=now;
                            aa[now].le=rii;
                            rii=now;
                        }
                    }
                    else
                    {
                        if(flag%2==0)
                        {
                            stri[++heri]=aa[rii].val;
                            aa[aa[rii].le].ri=-1;
                            rii=aa[rii].le;
                        }
                        else
                        {
                            stri[++heri]=aa[lee].val;
                            aa[aa[lee].ri].le=-1;
                            lee=aa[lee].ri;
                        }
                    }
                    continue;
                }
                if(tt==2)
                {
                    scanf("%s",d);
                    if(strcmp(d,"R")==0)
                    {
                        aa[++now].val=stri[heri--];
                        if(flag%2==0)
                        {
                            aa[now].ri=-1;
                            aa[rii].ri=now;
                            aa[now].le=rii;
                            rii=now;
                        }
                        else
                        {
                            aa[now].le=-1;
                            aa[lee].le=now;
                            aa[now].ri=lee;
                            lee=now;
                        }
                    }
                    else
                    {
                        if(flag%2==0)
                        {
                            stle[++hele]=aa[lee].val;
                            aa[aa[lee].ri].le=-1;
                            lee=aa[lee].ri;
                        }
                        else
                        {
                            stle[++hele]=aa[rii].val;
                            aa[aa[rii].le].ri=-1;
                            rii=aa[rii].le;
                        }
                    }
                    continue;
                }

                if(tt==3)
                {
                    scanf("%s",d);
                    int kkk;
                    scanf("%d",&kkk);
                    now++;
                    aa[now].val=kkk;
                    if(strcmp(d,"L")==0)
                    {
                        if(flag%2==0)
                        {
                            aa[now].ri=lee;
                            aa[now].le=-1;
                            aa[lee].le=now;
                            lee=now;
                        }
                        else
                        {
                            aa[now].le=rii;
                            aa[now].ri=-1;
                            aa[rii].ri=now;
                            rii=now;
                        }
                    }
                    else
                    {
                        if(flag%2==0)
                        {
                            aa[now].le=rii;
                            aa[now].ri=-1;
                            aa[rii].ri=now;
                            rii=now;
                        }
                        else
                        {
                            aa[now].ri=lee;
                            aa[now].le=-1;
                            aa[lee].le=now;
                            lee=now;
                        }
                    }
                    continue;
                }
                if(tt==4)
                {
                    scanf("%s",d);
                    if(strcmp(d,"L")==0)
                    {
                        if(flag%2==0)
                        {
                            lee=aa[lee].ri;
                            aa[lee].le=-1;
                        }
                        else
                        {
                            rii=aa[rii].le;
                            aa[rii].ri=-1;
                        }
                    }
                    else
                    {
                        if(flag%2==0)
                        {
                            rii=aa[rii].le;
                            aa[rii].ri=-1;
                        }
                        else
                        {
                            lee=aa[lee].ri;
                            aa[lee].le=-1;
                        }
                    }
                }
            }
            //以上是分別處理7種不同操作
            
            
            //下面是輸出部分,因為flag的原因,在輸出連結串列部分的時候也得判斷正反
            int fuck=0;
            for(int i=1;i<=hele;i++)
            {
                if(fuck==0)
                {
                    cout<<stle[i];
                    fuck=1;
                }
                else
                    cout<<" "<<stle[i];
            }
            if(flag%2==0)
            {
                while(lee!=-1)
                {
                    if(fuck==0)
                    {
                        cout<<aa[lee].val;
                        fuck=1;
                    }
                    else
                        cout<<" "<<aa[lee].val;
                    lee=aa[lee].ri;
                }
            }
            else
            {
                while(rii!=-1)
                {
                    if(fuck==0)
                    {
                        cout<<aa[rii].val;
                        fuck=1;
                    }
                    else
                        cout<<" "<<aa[rii].val;
                    rii=aa[rii].le;
                }
            }
            for(int i=heri;i>0;i--)
            {
                if(fuck==0)
                {
                    cout<<stri[i];
                    fuck=1;
                }
                else
                    cout<<" "<<stri[i];
            }
            cout<<endl;
        }
    }
}


相關推薦

HDU 4286 Data Handler 雙向連結串列

                                                 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) P

手寫LinkedList雙向連結串列

手寫LinkedList(雙向連結串列) 系統jdk裡的LinkedList是由一個個節點連線起來的,節點就相當於一個物件,裡面有資料域和指標域,資料域是存放資料用的,指標域就是指向下一個節點 從而相連線的 這裡是一個節點 那麼連結串列裡是什麼樣子的呢

Objective-C之Autorelease Pool底層實現原理記錄雙向連結串列以及在Runloop中是如何參與進去的

最近需要重新整理知識點備用,把一些重要的原理都搞了一遍 前言 int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, a

c++stl的list雙向連結串列

1.list初始化: (1)list<int>  t;  //沒有任何元素 (2)list<int>  t(10);  //建立有10個元素的連結串列 (3)lis

資料結構與算法系列五雙向連結串列

1.引子 1.1.為什麼要學習資料結構與演算法? 有人說,資料結構與演算法,計算機網路,與作業系統都一樣,脫離日常開發,除了面試這輩子可能都用不到呀! 有人說,我是做業務開發的,只要熟練API,熟練框架,熟練各種中介軟體,寫的程式碼不也能“飛”起來嗎? 於是問題來了:為什麼還要學習資料結構與演算法呢?

HDU 6215 Brute Force Sorting雙向連結串列+佇列

Brute Force Sorting Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 2304    Acce

資料結構與演算法JavaScript描述讀書筆記js實現連結串列-雙向連結串列

雙向連結串列 雙向連結串列的 remove() 方法比單向連結串列的效率更高,因為不需要再查詢前驅節點了 //建立建構函式建立節點 function Node(element){ this.element = element; this.next = null; th

劍指offer題解二叉樹與雙向連結串列

題目描述 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。   解題思路   中序遍歷搜尋二叉樹,用pre儲存中序遍歷的前一個節點,cur為當前節點,然後使pre->right=cu

Lava連結串列雙向連結串列---介面實現

在Java中連標配的結點需要用類來封裝,下面的簡單的雙向連結串列實現: class Node { private Object data; private Node next; public Node(Object data) {

線性表陣列、單鏈表、靜態連結串列、迴圈連結串列雙向連結串列

線性表的定義 線性表(List):零個或多個數據元素的有限序列。 有幾個地方需要強調: 首先它是一個序列,也就是說元素之間是有順序的,若元素存在多個,則第一個元素無前驅,最後一個元素無後繼,其他每個元素都有且只有一個前驅和後繼。 然後線性表強調的是有限的。 最

資料結構——線性表 順序表、單鏈表、靜態連結串列、迴圈連結串列雙向連結串列

提示:以下內容不適合零基礎人員,僅供筆者複習之用。 一、線性結構的基本特徵: 1.集合中必存在唯一的一個“第一元素”; 2.集合中必存在唯一的一個 “最後元素”; 3.除最後元素在外,均有 唯一的後繼; 4.除第一元素之外,均有 唯一的前驅。 如:j

c++ stl list環狀雙向連結串列

1.list   相較於vector的連續線性空間,list就顯得複雜很多,它的好處是每次插入或刪除一個元素,就配置或釋放一個元素的空間。因此,list對空間的運用有絕對的精確,一點也不浪費。而且,對於任何位置的元素插入和元素移除,list永遠是常數時間。   list的節

C++ 類模板小結雙向連結串列的類模板實現

一、類模板定義 定義一個類模板:template<class 模板引數表> class 類名{ // 類定義...... };其中,template 是宣告類模板的關鍵字,表示宣告一個模板,模板引數可以是一個,也可以是多個,可以是型別引數,也可以是非型別引數。型

LeetCode Sliding Window Maximum 滑動視窗雙向連結串列實現佇列效果

思路: 使用雙向連結串列(LinkedList,LinkedList類是雙向列表,列表中的每個節點都包含了對前一個和後一個元素的引用)。 雙向連結串列的大小就是視窗的個數,每次向視窗中增加一個元素時,如果比視窗中最後一個大,就刪除視窗中最後一個,以此類推,來

Leetcode 146 LRU Cache雙向連結串列+STL

解題思路:用一個雙向連結串列,維護一個最近訪問次序,用map記錄對應key的結點指標。對於get請求,需要將當前結點移動到連結串列的頭位置;對於put操作,如果是更新,則同樣將當前結點移動到頭位置,如果不是更新,則在頭位置插入一個新結點。如果連結串列長度超過快取上限,則刪除末

一步一步寫演算法雙向連結串列

【 宣告:版權所有,歡迎轉載,請勿用於商業用途。  聯絡信箱:feixiaoxing @163.com】     前面的部落格我們介紹了單向連結串列。那麼我們今天介紹的雙向連結串列,顧名思義,就是資料本身具備了左邊和右邊的雙向指標。雙向連結串列相比較單向連結串列,主要有下

連結串列倒序問題雙向連結串列的基礎運用

#include <stdio.h> #include <stdlib.h> struct node { int key; struct node *next,*before;//結構中包含前向指標before,後向指標next };

HDU 4286 Data Handler --雙端佇列

#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> #inc

資料結構之線性表順序表,單鏈表,迴圈連結串列雙向連結串列-- 圖書管理系統

順序表 #include <iostream> #include <cstring> #include <cstdlib>///exit()標頭檔案exit(0):正常執行程式並退出程式。exit(1):非正常執行導致退出程式 #incl

bzoj 4548: 小奇的糖果 && bzoj 3658: Jabberwocky雙向連結串列+樹狀陣列

Time Limit: 20 Sec  Memory Limit: 1024 MBSubmit: 263  Solved: 107 [Submit][Status][Discuss] Description 平面上有n個點,每個點有k種顏色中的一個。 你可以選擇一條