题目链接
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 }
原文地址:https://www.cnblogs.com/wenzhixin/p/9129728.html
时间: 2024-10-12 14:12:37