UVa12657 - Boxes in a Line(數組模擬鏈表)

題目大意ios

你有一行盒子,從左到右依次編號爲1, 2, 3,…, n。你能夠執行四種指令:

1 X Y表示把盒子X移動到盒子Y左邊(若是X已經在Y的左邊則忽略此指令)。
2 X Y表示把盒子X移動到盒子Y右邊(若是X已經在Y的右邊則忽略此指令)。
3 X Y表示交換盒子X和Y的位置。
4 表示反轉整條鏈。數組

盒子個數n和指令條數m(1<=n,m<=100,000)ide

題解spa

用數組來模擬鏈表操做,對於每一個節點設置一個前驅和後繼。code

1操做是把x的前驅節點和x的後繼節點鏈接,y節點的前驅和x節點鏈接,x節點和y節點鏈接。blog

2,3,的作法和1差很少string

4操做因爲操做兩次就等於沒有操做,因此只要判斷它最終是否是執行了奇數次,若是是就把n個節點的前驅和後繼交換下。還有就是在執行1,2的時候若是以前4操做了奇數次,那麼1,2兩個執行的操做分別是2操做和1操做。it

代碼:io

  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <utility>
  6 #include <vector>
  7 #include <queue>
  8 using namespace std;
  9 #define INF 0x3f3f3f3f
 10 #define maxn 111111
 11 typedef long long LL;
 12 int nxt[maxn], pre[maxn];
 13 void init(int n)
 14 {
 15     for (int i = 1; i <= n;i++)
 16     {
 17         pre[i] = i - 1;
 18         nxt[i] = i + 1;
 19     }
 20     nxt[n] = 0;
 21     nxt[0] = 1; pre[0] = n;
 22 }
 23 void link(int l, int r)
 24 {
 25     pre[r] = l; nxt[l] = r;
 26 }
 27 int main()
 28 {
 29     int n, m,kase=0;
 30     while (scanf("%d%d", &n, &m) != EOF)
 31     {
 32         int rev = 0;
 33         init(n);
 34         while (m--)
 35         {
 36             int op, x, y;
 37             scanf("%d", &op);
 38             if (op == 4) rev = 1 - rev;
 39             else
 40             {
 41                 scanf("%d%d", &x, &y);
 42                 if ((op == 1 || op == 2) && rev) op = 3 - op;
 43                 if (op == 3&&nxt[y] == x) swap(x, y);
 44                 int lx, rx, ly, ry;
 45                 lx = pre[x]; rx = nxt[x];
 46                 ly = pre[y]; ry = nxt[y];
 47                 if (op == 1)
 48                 {
 49                     if (nxt[x]==y) continue;
 50                     link(lx, rx);
 51                     link(ly, x);
 52                     link(x, y);
 53                                                             
 54                 }
 55                 else if (op == 2)
 56                 {
 57                     if (nxt[y]==x) continue;
 58                     link(lx, rx);
 59                     link(x, ry);
 60                     link(y, x);
 61                 }
 62                 else
 63                 {
 64                     if (nxt[x] == y)
 65                     {
 66                         link(lx, y);
 67                         link(y, x);
 68                         link(x, ry);
 69                     }
 70                     else
 71                     {
 72                         link(lx, y);
 73                         link(y, rx);
 74                         link(ly, x);
 75                         link(x, ry);
 76                     }
 77                 }
 78             }
 79         }
 80         if (rev)
 81         {
 82             for (int i = 1; i <= n; i++) swap(pre[i], nxt[i]);
 83         }
 84         int pos;
 85         for (int i = 1; i <= n; i++)
 86         {
 87             if (pre[i] == 0)
 88             {
 89                 pos = i;
 90                 break;
 91             }
 92         }
 93         int cnt = 1;
 94         LL ans = 0;
 95         while (pos!=0)
 96         {
 97             if (cnt & 1) ans += pos;
 98             pos = nxt[pos];
 99             cnt++;
100         }
101         printf("Case %d: %I64d\n", ++kase,ans);
102     }
103     return 0;
104 }
View Code
相關文章
相關標籤/搜索