UVA 12657 Boxes in a Line

思路:

原版代码:

复制代码
 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 
 5 const int maxn = 100000 + 5;
 6 int n, left[maxn], right[maxn];
 7 /*left;编号为i的盒子左边的编号
 8 right:右边的编号
 9 inv表示有没有执行过操作4(如果inv=1,再执行一次操作4,则inv变为0)
10 */
11 inline void link(int L, int R) //L和R连接
12 {
13   right[L] = R; left[R] = L;
14 }
15 
16 int main() 
17 {
18   int m, kase = 0;
19   while(scanf("%d%d", &n, &m) == 2) 
20   {
21     for(int i = 1; i <= n; i++) 
22     {
23       left[i] = i-1;
24       right[i] = (i+1) % (n+1);//第n个右边是第1个
25     }
26     right[0] = 1; left[0] = n;
27     int op, X, Y, inv = 0;
28 
29     while(m--) 
30     {
31       scanf("%d", &op);
32       if(op == 4) inv = !inv;
33       else 
34       {
35         scanf("%d%d", &X, &Y);
36         if(op == 3 && right[Y] == X) swap(X, Y);//X在Y右边,交换后X在Y左边 YX->XY
37         if(op != 3 && inv) op = 3 - op;// 1,2要受inv的影响,AB inv后变成BA,相当于把1,2反过来
38         if(op == 1 && X == left[Y]) continue;//X已经在Y左边
39         if(op == 2 && X == right[Y]) continue;//X已经在Y右边
40 
41         int LX = left[X], RX = right[X], LY = left[Y], RY = right[Y];
42         if(op == 1) //X到Y左
43         {
44           link(LX, RX); //X从链表中取出,连接X左右节点
45           link(LY, X);//X与Y左边的节点相连
46           link(X, Y);//X连接到Y左边
47         }
48         else if(op == 2) //X到Y右
49         {
50           link(LX, RX); link(Y, X); link(X, RY);
51         }
52         else if(op == 3) //X Y交换
53         {
54           if(right[X] == Y) //Y在X右边 LX->X->Y->RY
55           { 
56               link(LX, Y); //LX->Y
57               link(Y, X);//LX->Y->X
58               link(X, RY); //LX->Y->X->RY
59           }
60           else 
61           { 
62               link(LX, Y);
63               link(Y, RX); 
64               link(LY, X); 
65               link(X, RY);
66           }
67         }
68       }
69     }
70 
71     int b = 0;
72     long long ans = 0;
73     for(int i = 1; i <= n; i++) 
74     {
75       b = right[b];
76       if(i % 2 == 1) ans += b;//奇数位置加上其盒子编号
77     }
78     if(inv && n % 2 == 0) 
79         ans = (long long)n*(n+1)/2 - ans;
80     printf("Case %d: %lld\n", ++kase, ans);
81   }
82   return 0;
83 }
复制代码

 

posted @   付玬熙  阅读(253)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
主题色彩