【UVA 12657】Boxes in a Line 题解(静态双向链表)
  VJeqq9jk2lCR 2023年11月02日 45 0

您在编号为1的表格上有n个方框。n从左到右。您的任务是模拟4 命令类型: •1 X Y:将框X向左移动到Y(如果X已经是Y的左侧,则忽略此项) •2 X Y:将框X向右移动到Y(如果X已经是Y的右侧,则忽略此项) •3 X Y:交换盒X和Y •4:反转整条线路。 命令保证有效,即X不等于Y。 例如,如果n=6,在执行1 1 4之后,该行变为2 3 1 4 5 6。然后在执行之后 2 3 5,直线变为2 1 4 5 3 6。然后在执行3 1 6之后,该行变为2 6 4 5 3 1。 然后在执行4之后,行变为1 3 5 4 6 2

输入 最多有10个测试用例。每个测试用例以包含2个整数n,m的行开始 (1≤n,m≤100000)。以下m行中的每一行都包含一个命令。 输出 对于每个测试用例,在奇数索引位置打印数字的和。位置编号为1到n 从左到右。

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

思路

实现静态双向链表及插入元素、删除元素、移动元素、交换元素等操作。交换元素a和b时有三种情况,ab相邻且a在b前、ab相邻且a在b后、ab不相邻,要分情况解决。用rev来标记链表是否被翻转,若被翻转输出反向奇数索引之和,反向奇数索引之和等于所有索引之和减去正向奇数索引之和。

AC代码

#include <iostream>
#include <list>
#include <algorithm>
#define AUTHOR "HEX9CF"
using namespace std;

#define maxn 100005

int n, m;
int rev = 1;
int cmd;
int l[maxn], r[maxn];
int x, y;
int k = 1;

void link(int a, int b)
{
    r[a] = b;
    l[b] = a;
}

void del(int x)
{
    link(l[x], r[x]);
}

void ins(int a, int c, int b)
{
    link(a, c);
    link(c, b);
}

void swp(int x, int y)
{
    if (l[y] == x)
    {
        int a = l[x];
        int b = r[y];
        link(a, y);
        link(y, x);
        link(x, b);
    }
    else if (r[y] == x)
    {
        int a = l[y];
        int b = r[x];
        link(a, x);
        link(x, y);
        link(y, b);
    }
    else
    {
        int a = l[x];
        int b = r[x];
        int c = l[y];
        int d = r[y];
        link(c, x);
        link(x, d);
        link(a, y);
        link(y, b);
    }
}

void print()
{
    cout << "l ";
    for (int i = 1; i <= n; i++)
    {
        cout << l[i] << " ";
    }
    cout << endl
         << "r ";
    for (int i = 1; i <= n; i++)
    {
        cout << r[i] << " ";
    }
    cout << endl;
}

void show()
{
    int t = 0;
    for (int i = 1; i <= n; i++)
    {
        t = r[t];
        cout << t << " ";
    }
    cout << endl;
}

int main()
{
    while (cin >> n >> m)
    {
        rev = 1;
        for (int i = 1; i <= n + 1; i++)
        {
            l[i] = i - 1;
            r[i] = (i + 1) % (n + 1);
        }
        l[0] = n;
        r[0] = 1;
        // show();

        for (int i = 0; i < m; i++)
        {
            cin >> cmd;
            if (4 == cmd)
            {
                rev *= -1;
                continue;
            }
            cin >> x >> y;
            if ((1 == cmd && rev > 0) || (2 == cmd && rev < 0))
            {
                // 将盒子x 移动到y 的左侧
                // cout << "1 " << rev << endl;
                del(x);
                ins(l[y], x, y);
            }
            else if ((2 == cmd && rev > 0) || (1 == cmd && rev < 0))
            {
                // 将盒子x 移动到y 的右侧
                // cout << "2 " << rev << endl;
                del(x);
                ins(y, x, r[y]);
            }
            else if (3 == cmd)
            {
                // 交换盒子x 和y 的位置。
                // cout << x << " swap " << y << endl;
                swp(x, y);
            }
            // show();
        }
        // print();
        // show();
        int t = 0;
        long long sum = 0, j = 0;
        for (int i = 1; i <= n; i++)
        {
            t = r[t];
            sum += t;
            if (i % 2)
            {
                j += t;
            }
        }
        // cout << sum << endl;
        if (!(n % 2) && (rev < 0))
        {
            j = sum - j;
        }
        cout << "Case " << k << ": " << j << endl;
        k++;
    }
    return 0;
}
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

VJeqq9jk2lCR
最新推荐 更多