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 }
Problem UVA12657-Boxes in a Line(數組模擬雙鏈表)