1. 程式人生 > >Problem UVA12657-Boxes in a Line(數組模擬雙鏈表)

Problem UVA12657-Boxes in a Line(數組模擬雙鏈表)

tdi begin lin val 前驅 不知道 who HERE task

Problem UVA12657-Boxes in a Line

Accept: 725 Submit: 9255

Time Limit: 1000 mSec

技術分享圖片 Problem Description

You have n boxes in a line on the table numbered 1...n from left to right. Your task is to simulate 4 kinds of commands:

? 1 X Y : move box X to the left to Y (ignore this if X is already the left of Y )

? 2 X Y : move box X to the right to Y (ignore this if X is already the right of Y )

? 3 X Y : swap box X and Y

? 4: reverse the whole line.

Commands are guaranteed to be valid, i.e. X will be not equal to Y . For example, if n = 6, after executing 1 1 4, the line becomes 2 3 1 4 5 6. Then after executing 2 3 5, the line becomes 2 1 4 5 3 6. Then after executing 3 1 6, the line becomes 2 6 4 5 3 1. Then after executing 4, then line becomes 1 3 5 4 6 2

技術分享圖片 Input

There will be at most 10 test cases. Each test case begins with a line containing 2 integers n, m (1 ≤ n,m ≤ 100,000). Each of the following m lines contain a command.

技術分享圖片 Output

For each test case, print the sum of numbers at odd-indexed positions. Positions are numbered 1 to n from left to right.

技術分享圖片 Sample Input

6 4 1 1 4 2 3 5 3 1 6 4 6 3 1 1 4 2 3 5 3 1 6 100000 1 4

技術分享圖片 Sample output

Case 1: 12

Case 2: 9

Case 3: 2500050000

題解:數組模擬雙鏈表。雖然是模擬,但是操作起來並不是很簡單,應用雙鏈表比較自然,困難的是中間的各種修改,我的第一份代碼用的是學C語言的時候類似指針的操作,什麽pre的next是x的next,next的pre是什麽什麽之類的,這種操作比較容易錯的就是順序問題,一旦順序搞錯,信息就會丟失,然後就不知道連到哪了,紫書上的方法十分優秀,提前先記錄下來前驅、後繼,這樣不會丟失信息,順序什麽的就不用考慮了,然後把連邊的操作封裝到函數裏,這樣更是簡化了思考,或者說是縮短了思維長度,經過這兩個操作,原來十分費勁的修改關系就變得幾乎是無腦操作了,這麽好的方法一定要學會。

代碼完全是按照紫書寫的......

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cstdio>
 5 using namespace std;
 6 typedef long long LL;
 7 
 8 const int maxn = 100000+10;
 9 int Next[maxn],Pre[maxn];
10 int cnt = 1;
11 
12 void Link(int p,int n){
13     Next[p] = n,Pre[n] = p;
14 }
15 
16 int main()
17 {
18     //freopen("input.txt","r",stdin);
19     int n,m;
20     while(~scanf("%d%d",&n,&m)){
21         for(int i = 1;i <= n;i++){
22             Next[i] = (i+1)%(n+1);
23             Pre[i] = i-1;
24         }
25         Next[0] = 1,Pre[0] = n;
26         int x,y,ope,inv = 0;
27         for(int i = 1;i <= m;i++){
28             scanf("%d",&ope);
29             if(ope == 4) inv = !inv;
30             else{
31                 scanf("%d%d",&x,&y);
32                 if(inv && (ope==1 || ope==2)) ope = 3-ope;
33                 if(ope==1 && Pre[y]==x) continue;
34                 if(ope==2 && Pre[x]==y) continue;
35                 if(ope==3 && Next[y]==x) swap(x,y);
36                 int nx = Next[x],px = Pre[x];
37                 int ny = Next[y],py = Pre[y];
38                 if(ope == 1){
39                     Link(px,nx);Link(py,x);Link(x,y);
40                 }
41                 if(ope == 2){
42                     Link(px,nx);Link(y,x);Link(x,ny);
43                 }
44                 if(ope == 3){
45                     if(Next[x]==y){
46                         Link(px,y);Link(y,x);Link(x,ny);
47                     }
48                     else{
49                         Link(px,y);Link(y,nx);
50                         Link(py,x);Link(x,ny);
51                     }
52                 }
53             }
54         }
55         LL ans = 0;
56         int t = Next[0];
57         for(int i = 1;i <= n;i++){
58             if(i%2 == 1) ans += t;
59             t = Next[t];
60         }
61         if(inv && n%2==0) ans = 1LL*n*(n+1)/2-ans;
62         printf("Case %d: %lld\n",cnt++,ans);
63     }
64     return 0;
65 }

Problem UVA12657-Boxes in a Line(數組模擬雙鏈表)