UVA12657 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 the right to Y (ignore this if X is already the right of Y )

? 3 X Y : swap box X and Y

? 4: reverse the whole line.

Commands are guaranteed to be valid, i.e. X will be not equal to Y .

For example, if n = 6, after executing 1 1 4, the line becomes 2 3 1 4 5 6. Then after executing

2 3 5, the line becomes 2 1 4 5 3 6. Then after executing 3 1 6, the line becomes 2 6 4 5 3 1.

Then after executing 4, then line becomes 1 3 5 4 6 2

Input

There will be at most 10 test cases. Each test case begins with a line containing 2 integers n, m

(1 ≤ n, m ≤ 100, 000). Each of the following m lines contain a command.

Output

For each test case, print the sum of numbers at odd-indexed positions. Positions are numbered 1 to n

from left to right.

Sample Input

6 4

1 1 4

2 3 5

3 1 6

4

6 3

1 1 4

2 3 5

3 1 6

100000 1

4

Sample Output

Case 1: 12

Case 2: 9

Case 3: 2500050000

题目大意:你有一行盒子,从左到右编号为1~n,现在有4种操作。

1 X Y 表示把X盒子移到Y盒子的左边

2 X Y 表示把X盒子移到Y盒子的右边

3 X Y 表示交换X盒子和Y盒子的位置

4 将盒子顺序全部翻转过来

最后问进行m次操作后,奇数位置的盒子编号和为多少

思路:最好的方法使用双向链表。这里用数组的方法模拟,用Left[i]和Right[i]

分别表示编号为i的盒子左边和右边的盒子编号(为0表示没有盒子)。通过模拟

链表连接的方法改变连接顺序。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

int Left[100010],Right[100010];

void link(int L,int R)
{
    Right[L] = R;
    Left[R] = L;
}

int main()
{
    int n,m,kase = 0;
    while(cin >> n >> m)
    {
        for(int i = 1; i <= n; i++)
        {
            Left[i] = i-1;
            Right[i] = (i+1) % (n+1);
        }
        Right[0] = 1;
        Left[0] = n;
        int inv = 0,X,Y;
        while(m--)
        {
            int op;
            cin >> op;
            if(op == 4)
                inv = !inv;
            else
            {
                cin >> X >> Y;
                if(op == 3 && Right[Y] == X)
                    swap(X,Y);
                if(op != 3 && inv)
                    op = 3 - op;
                if(op == 1 && X == Left[Y])
                    continue;
                if(op == 2 && X == Right[Y])
                    continue;

                int LX,RX,LY,RY;
                LX = Left[X], RX = Right[X], LY = Left[Y], RY = Right[Y];
                if(op == 1)
                {
                    link(LX,RX);
                    link(LY,X);
                    link(X,Y);
                }
                else if(op == 2)
                {
                    link(LX,RX);
                    link(Y,X);
                    link(X,RY);
                }
                else if(op == 3)
                {
                    if(Right[X] == Y)
                    {
                        link(LX,Y);
                        link(Y,X);
                        link(X,RY);
                    }
                    else
                    {
                        link(LX,Y);
                        link(Y,RX);
                        link(LY,X);
                        link(X,RY);
                    }
                }
            }
        }

        int num = 0;
        long long ans = 0;
        for(int i = 1; i <= n; i++)
        {
            num = Right[num];
            if(i&1)
                ans += num;
        }
        if(inv && !(n&1))
            ans = (long long)n*(n+1)/2 - ans;
        cout << "Case " << ++kase <<": " << ans << endl;
    }

    return 0;
}
时间: 2024-10-10 02:08:41

UVA12657 Boxes in a Line【双向链表】【数组模拟】的相关文章

UVa 12657 Boxes in a Line(数组模拟双链表)

题目链接 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

【日常学习】【模拟双向链表】【疑问】Uva12657 - Boxes in a Line题解

这道题目我做的不对.事实上,我按书上的标程抄的,几乎一模一样,我认为他没有什么错误,可我就是不知道为什么我在代码仓库下的刘汝佳写的程序就AC,我写的就WA.跳了一下午,两程序样例输出完全一样(奇怪的是和书上答案不一样)一个字一个字的比对,就是找不出哪里不一样.我觉得极少不一样的地方应该没有影响,哪位大神愿意给看看? 这是一道双向链表,同样没有用指针,而是用两个数组模拟,道理和上面的那道非指针单向链表题目一样 刘汝佳的代码 // UVa12657 Boxes in a Line // Rujia

UVa12657 - Boxes in a Line(数组模拟链表)

题目大意 你有一行盒子,从左到右依次编号为1, 2, 3,…, n.你可以执行四种指令: 1 X Y表示把盒子X移动到盒子Y左边(如果X已经在Y的左边则忽略此指令).2 X Y表示把盒子X移动到盒子Y右边(如果X已经在Y的右边则忽略此指令).3 X Y表示交换盒子X和Y的位置.4 表示反转整条链. 盒子个数n和指令条数m(1<=n,m<=100,000) 题解 用数组来模拟链表操作,对于每个节点设置一个前驱和后继. 1操作是把x的前驱节点和x的后继节点连接,y节点的前驱和x节点连接,x节点和y

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

Uva12657 (Boxes in a Line)移动盒子

UVA 12657 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 4kinds 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

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; } //在双向链表这样复

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

O - Boxes in a Line

O - Boxes in a Line Time Limit:1000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Description 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 t

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