Problem UVA12657-Boxes in a Line(数组模拟双链表)

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 }

猜你喜欢

转载自www.cnblogs.com/npugen/p/9501609.html
今日推荐