Uva 12657 移动盒子(双向链表)

题意:

你有一行盒子,从左到右依次编号为1, 2, 3,…, n。可以执行以下4种指令:
1 X Y表示把盒子X移动到盒子Y左边(如果X已经在Y的左边则忽略此指令)。
2 X Y表示把盒子X移动到盒子Y右边(如果X已经在Y的右边则忽略此指令)。
3 X Y表示交换盒子X和Y的位置。
4 表示反转整条链。

分析:

从操作1,2来看, 需要有一个数据结构, 记录每个盒子左边和右边是什么。

操作4如果真的模拟复杂度较高也比较麻烦, 可以考虑建一个标记, 表示有没执行过操作4

但是注意了 如果执行了操作4后, 如果操作1 2操作不变的话, 那么操作1就是2,2 就是1(放在左边 + 反转 = 放在右边)

双向链表有一个比较实用的函数

意思就是将L,R两个元素相连, L在R的左边, R在L的右边。

 1 #include <bits/stdc++.h>
 2 const int maxn =  100000 + 7;
 3 int n, left[maxn], right[maxn];
 4 void link(int L, int R){//第一个参数是 L,第二个是R,
 5     right[L] = R;
 6     left[R] = L;
 7 }
 8 int main()
 9 {
10     int m, kase = 0;
11     while(scanf("%d %d", &n, &m) == 2){
12         for(int i = 1; i <= n; i++){
13             left[i] = i -1;
14             right[i] = (i+1) % (n+1);
15         }
16         right[0] = 1;//注意0右边是1 左边是 n
17         left[0] = n;
18         int op, X, Y, inv = 0;
19         while(m--){
20             scanf("%d", &op);
21             if(op == 4) inv = !inv;
22             else {
23                 scanf("%d%d",&X, &Y);
24                 if(op == 3 && right[Y] == X)
25                    std::swap(X,Y);
26                 if(op != 3 && inv) op = 3 - op;
27                 if(op == 1 && X == left[Y]) continue;
28                 if(op == 2 && X == right[Y]) continue;
29
30                 int LX = left[X], RX = right[X], LY = left[Y], RY = right[Y];
31                 if(op == 1){
32                     link(LX,RX); link(LY,X); link(X,Y);
33                 }
34                 else if(op == 2){
35                     link(LX,RX); link(Y,X); link(X,RY);
36                 }
37                 else if(op == 3){
38                     if(right[X] == Y){
39                         link(LX,Y); link(Y,X);
40                         link(X,RY);
41                     }
42                     else {
43                         link(LX,Y);
44                         link(Y,RX);
45                         link(LY,X);
46                         link(X,RY);
47                     }
48                 }
49             }
50         }
51         int b = 0;
52         long long ans = 0;
53         for(int i = 1; i <= n; i++){
54             b = right[b];
55             if(i % 2 == 1) ans += b;
56         }
57         if(inv && n % 2 == 0) ans = (long long) n * (n+1)/2 - ans;
58         printf("Case %d: %lld\n", ++kase, ans);
59     }
60 }
时间: 2024-08-08 21:53:37

Uva 12657 移动盒子(双向链表)的相关文章

UVa 12657 Boxes in a Line(双向链表的应用)

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 th

uva 12657 - Boxes in a Line(AC和TLE的区别,为什么说STL慢..)

用STL中的list写的,TLE #include<cstdio> #include<iostream> #include<cstring> #include<list> #include<algorithm> using namespace std; list<int> l; list<int>::iterator it1,it2,it3,it4,it5,it; void work(int a,int a1=1,int

Uva 12657 Boxes in a Line 双向链表

操作4比较特殊,为了避免一次性修改所有元素的指针,由于题目只要求输出奇数盒子的编号,所以我们可以灵活的根据是否进行过操作4对操作1 操作2 进行改动 操作3不受操作4影响 上代码.... #include<cstdio> #include<algorithm> const int maxn=100000+5; int right[maxn],left[maxn]; void link (int L,int R){ right[L]=R;left[R]=L; } //在双向链表这样复

双向链表 Boxes in a Line UVA - 12657

首先记录一下对链表的理解,最初看链表是在教材上看的,上面是用结构体, 理解起来还不是很困难,我也以为自己懂了,然而看到紫书上链表用的是数组(UVA11988),真的是..到最后把他的代码背下来了都还是有点晕(/(ㄒoㄒ)/~~),那个时候做题有点匆忙,也就没深究,不过后面那道(也就是这道)也就没再写了,差不多隔了一个月吧,有那么一点点感觉就是这次没看代码自己写过一遍后. 单向每一个结构体有两个元素(或者更多),其中一个是下一个元素的地址,其他的是他本身有的东西,在这道题中,1 2 3 4 5,

UVA 12657 Boxes in a Line(双向链表+小技巧)

题意:对于一行按照顺序排列盒子数字与位置都为 1,2,3,4....n 执行四种操作 c = 1    x 放到 y 的左边 c =2     x 放到 y 的右边 c =3 交换 x, y c =4 颠倒链 最后求出奇数位置的数的总和 题解:直接维护无论如何每次每次都需要维护一段区间的位置,因此不去看位置.只需要知道每个盒子左边是哪个盒子右边是哪个盒子 这样就直接使用双向链表维护,接着颠倒时注意只是标记就好 最后注意几个细节: 首先颠倒后1与2的交换需要互换: 维护链表时可以提取出一个函数,每

Uva 12657 双向链表

题目链接:https://uva.onlinejudge.org/external/126/12657.pdf 题意: 给你一个从1~n的数,然后给你操作方案 • 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

Boxes in a Line UVA - 12657 (双向链表)

题目链接:https://vjudge.net/problem/UVA-12657 题目大意:输入n,m  代表有n个盒子 每个盒子最开始按1~n排成一行  m个操作, 1 x y  :把盒子x放到y的左边 2 x y: 把盒子x放到y 的右边 3 x y:调换x y盒子的位置 4    表示反转整条链 思路:也是很明显的暴力 模拟 .  但是值得提的是 虽然是暴力,但是却是用的双向链表来暴力. 有很多要注意的地方 : 当操作4的时候,我们可以把本次操作记录一下,不必直接把全部的位置反转 试想一

uva 12657(双向链表)

一定要注意swap(x, y),x, y可能相邻! #include <cstdio> #define N 100005 #define ll long long int n, m; struct node{ int l, r; node() : l(0), r(0) {} node(int l_, int r_) : l(l_), r(r_) {} }num[N]; void init() { for(int i = 0; i <= n + 1; i++) num[i].l = i -

UVa 12657 Boxes in a Line(应用双链表)

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 th