UVA 12657 Boxes in a Line
思路:
原版代码:
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 5 const int maxn = 100000 + 5; 6 int n, left[maxn], right[maxn]; 7 /*left;编号为i的盒子左边的编号 8 right:右边的编号 9 inv表示有没有执行过操作4(如果inv=1,再执行一次操作4,则inv变为0) 10 */ 11 inline void link(int L, int R) //L和R连接 12 { 13 right[L] = R; left[R] = L; 14 } 15 16 int main() 17 { 18 int m, kase = 0; 19 while(scanf("%d%d", &n, &m) == 2) 20 { 21 for(int i = 1; i <= n; i++) 22 { 23 left[i] = i-1; 24 right[i] = (i+1) % (n+1);//第n个右边是第1个 25 } 26 right[0] = 1; left[0] = n; 27 int op, X, Y, inv = 0; 28 29 while(m--) 30 { 31 scanf("%d", &op); 32 if(op == 4) inv = !inv; 33 else 34 { 35 scanf("%d%d", &X, &Y); 36 if(op == 3 && right[Y] == X) swap(X, Y);//X在Y右边,交换后X在Y左边 YX->XY 37 if(op != 3 && inv) op = 3 - op;// 1,2要受inv的影响,AB inv后变成BA,相当于把1,2反过来 38 if(op == 1 && X == left[Y]) continue;//X已经在Y左边 39 if(op == 2 && X == right[Y]) continue;//X已经在Y右边 40 41 int LX = left[X], RX = right[X], LY = left[Y], RY = right[Y]; 42 if(op == 1) //X到Y左 43 { 44 link(LX, RX); //X从链表中取出,连接X左右节点 45 link(LY, X);//X与Y左边的节点相连 46 link(X, Y);//X连接到Y左边 47 } 48 else if(op == 2) //X到Y右 49 { 50 link(LX, RX); link(Y, X); link(X, RY); 51 } 52 else if(op == 3) //X Y交换 53 { 54 if(right[X] == Y) //Y在X右边 LX->X->Y->RY 55 { 56 link(LX, Y); //LX->Y 57 link(Y, X);//LX->Y->X 58 link(X, RY); //LX->Y->X->RY 59 } 60 else 61 { 62 link(LX, Y); 63 link(Y, RX); 64 link(LY, X); 65 link(X, RY); 66 } 67 } 68 } 69 } 70 71 int b = 0; 72 long long ans = 0; 73 for(int i = 1; i <= n; i++) 74 { 75 b = right[b]; 76 if(i % 2 == 1) ans += b;//奇数位置加上其盒子编号 77 } 78 if(inv && n % 2 == 0) 79 ans = (long long)n*(n+1)/2 - ans; 80 printf("Case %d: %lld\n", ++kase, ans); 81 } 82 return 0; 83 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步