1. 程式人生 > >UVa 12657 Boxes in a Line(數組模擬雙鏈表)

UVa 12657 Boxes in a Line(數組模擬雙鏈表)

amp 真的 解題思路 style freopen AI void right code

題目鏈接

 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 }

UVa 12657 Boxes in a Line(數組模擬雙鏈表)