UVa 12657 Boxes in a Line(数组模拟双链表)

题目链接

 1 /*
 2 问题
 3 将一排盒子经过一系列的操作后,计算并输出奇数位置上的盒子标号之和
 4 
 5 解题思路
 6 由于数据范围很大,直接数组模拟会超时,所以采用数组模拟的链表,left[i]和right[i]分别表示i号盒子的左边是谁和右边
 7 是谁。特别提醒,4这个操作可以采用其他的办法去标记,而不必真的去模拟交换,否则会超时。 
 8 */
 9  
10 #include<cstdio>
11 #include<algorithm>
12 
13 using namespace std;
14 const int maxn=101000;
15 int n,left[maxn],right[maxn];
16 
17 void link(int r,int l); 
18 
19 int main()
20 {
21     //freopen("E:\\testin.txt","r",stdin);
22     int m,i,kase=1;
23     while(scanf("%d%d",&n,&m) != EOF){
24         for(i=0;i<=n;i++){
25             link(i,i+1);
26         }
27         left[0]=n;
28         right[n]=0;
29         
30         int op,x,y;
31         int inv=0;
32         while(m--){
33             scanf("%d",&op);
34             if(op == 4)    inv= !inv;
35             else{
36                 scanf("%d%d",&x,&y);
37                 if(op == 3 && right[y] == x) swap(x,y);
38                 if(op != 3 && inv) op= 3-op;
39                 if(op == 1 && x==left[y])    continue;
40                 if(op == 2 && x==right[y])    continue;
41                 
42                 int lx=left[x],rx=right[x],ly=left[y],ry=right[y];
43                 if(op == 1){
44                     link(lx,rx);
45                     link(ly,x);
46                     link(x,y);
47                 }else if(op == 2){
48                     link(lx,rx);
49                     link(y,x);
50                     link(x,ry);
51                 }else if(op == 3){
52                     if(right[x] == y){
53                         link(y,x);
54                         link(lx,y);
55                         link(x,ry);
56                     }
57                     else{
58                         link(lx,y);
59                         link(y,rx);
60                         link(ly,x);
61                         link(x,ry);
62                     }
63                 }
64             }
65         }
66         
67         int cou=0;
68         long long ans=0;
69         for(int i=1;i<=n;i++){
70             cou=right[cou];
71             //printf("#%d\n",cou);
72             if(i%2 == 1)    
73                 ans += cou;
74         }
75         if(inv && n%2 == 0)    ans = (long long)n*(n+1)/2 - ans;
76         printf("Case %d: %lld\n",kase++,ans);
77     }
78     return 0;
79 }
80 
81 void link(int l,int r)
82 {
83     right[l]=r;
84     left[r]=l;
85 }

 

posted @ 2018-06-03 17:03  Reqaw  阅读(210)  评论(0编辑  收藏  举报