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 - 1, num[i].r = i + 1;
}

void move2left(int x, int y)
{
    if(num[y].l == x) return ;
    int l, r;
    l = num[x].l, r = num[x].r;
    num[l].r = r, num[r].l = l;
    l = num[y].l, r = y;
    num[x].r = r, num[x].l = l;
    num[l].r = x, num[r].l = x;
}

void move2right(int x, int y)
{
    if(num[y].r == x) return ;
    int l, r;
    l = num[x].l, r = num[x].r;
    num[l].r = r, num[r].l = l;
    l = y,        r = num[y].r;
    num[x].r = r, num[x].l = l;
    num[l].r = x, num[r].l = x;
}

void Swap(int x, int y)
{
    int xl, xr, yl, yr;
    if(num[x].r == y) {
        xl = num[x].l, yr = num[y].r;
        num[xl].r = y, num[yr].l = x;
        num[y].l = xl, num[y].r = x;
        num[x].l = y, num[x].r = yr;
    }
    else if(num[x].l == y) {
        xr = num[x].r, yl = num[y].l;
        num[xr].l = y, num[yl].r = x;
        num[y].l = x, num[y].r = xr;
        num[x].l = yl, num[x].r = y;
    }
    else {
    xl = num[x].l, xr = num[x].r;
    yl = num[y].l, yr = num[y].r;
    num[xl].r = y, num[xr].l = y;
    num[yl].r = x, num[yr].l = x;
    num[x].l = yl, num[x].r = yr;
    num[y].l = xl, num[y].r = xr;
    }

}

int main()
{
    //freopen("out.txt", "w", stdout);
    int cases = 0;
    while(~scanf("%d%d", &n, &m))
    {
        cases++;
        init();
        int op, res = 1;
        for(int i = 1; i <= m; i++)
        {
            scanf("%d", &op);
            int x, y;
            if(op < 4) scanf("%d%d", &x, &y);
            if((op == 1 && res) || (op == 2 && !res))
                move2left(x, y);
            else if((op == 2 && res) || (op == 1 && !res))
                move2right(x, y);
            else if(op == 3)
                Swap(x, y);
            else res = !res;
        }
        ll sum = 0;
        if(res) {
            int t = num[0].r, c = 0;
            while(c < n) {
                c++;
                if(c % 2 == 1) sum += (ll)t;
                //printf("%d***\n", t);
                t = num[t].r;
            }
        }
        else {
            int t = num[n + 1].l, c = 0;
            //printf("%d***\n", t);
            while(c < n) {
                c++;
                if(c % 2 == 1) sum += (ll)t;
                //printf("%d***\n", t);
                t = num[t].l;
            }
        }
        printf("Case %d: %lld\n", cases, sum);
    }
    return 0;
}
时间: 2024-10-15 17:06:11

uva 12657(双向链表)的相关文章

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

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 移动盒子(双向链表)

题意: 你有一行盒子,从左到右依次编号为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后,

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 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