标签:链表 acm comm com problem turn equal NPU desc
Problem UVA12657-Boxes in a Line
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
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.
For each test case, print the sum of numbers at odd-indexed positions. Positions are numbered 1 to n from left to right.
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
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(数组模拟双链表)
标签:链表 acm comm com problem turn equal NPU desc
原文地址:https://www.cnblogs.com/npugen/p/9501609.html