uva -12657 Boxes in a Line(数组实现双向链表)

题目链接

题意 1 1 1 ~ n n n的数字原本按顺序摆好,接下来有四种操作。

  • 1 X Y 1 X Y 1XY :将 X X X移动到 Y Y Y的左边
  • 2 X Y 2 X Y 2XY :将 X X X移动到 Y Y Y的右边
  • 3 X Y 3 X Y 3XY :交换 X , Y X,Y X,Y的位置
  • 4 4 4 :翻转整个数字串
    经过这一系列操作后,最后输出奇数位上的数字和。

题解 :有移动到左右的操作,所以想到了双向链表。由于是第一次写双向链表,写得很精污。注意 ∑ i = 1 100000 \sum_{i = 1}^{100000} i=1100000会超出int范围,所以用 l o n g   l o n g long\ long long long。在交换 X , Y X,Y X,Y的位置的时候,要特判两个数字的位置是不是相邻的。

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int maxn = 1e5 + 7;

map<int, int> mp;
int n, m, op, x, y, l[maxn][2], cas;

void init() {
	//数组第二维,0表示左边,1表示右边
    l[0][1] = 1;
    l[n + 1][0] = n;
    for (int i = 1; i <= n; ++i) {
        l[i][0] = i - 1;
        l[i][1] = i + 1;
    }
    mp[1] = 0, mp[2] = 1;
}

void insert(int op, int x, int y) {
    if (l[y][op] == x) return;
    l[l[x][1]][0] = l[x][0];
    l[l[x][0]][1] = l[x][1];
    l[l[y][op]][op ^ 1] = x;
    l[x][op] = l[y][op];
    l[x][op ^ 1] = y;
    l[y][op] = x;
}

void exc(int x, int y) {
    int ll = l[x][0], lr = l[x][1];
    int rl = l[y][0], rr = l[y][1];
    if (lr == y) {
        l[ll][1] = y;
        l[y][1] = x;
        l[y][0] = ll;
        l[x][0] = y;
        l[x][1] = rr;
        l[rr][0] = x;
        return;
    }
    if (ll == y) {
        l[rl][1] = x;
        l[x][1] = y;
        l[x][0] = rl;
        l[y][0] = x;
        l[y][1] = lr;
        l[lr][0] = y;
        return;
    }
    l[ll][1] = y, l[lr][0] = y;
    l[rl][1] = x, l[rr][0] = x;
    l[x][0] = rl;
    l[x][1] = rr;
    l[y][0] = ll;
    l[y][1] = lr;
    
}

void print(int op) {
    int head;
    ll res = 0;
    if (op) head = 0;
    else head = n + 1;
    int f = n, cnt = 1;
    while (f--) {
        head = l[head][op];
        if (cnt & 1) res += head;
        cnt ^= 1;
    }
    printf("Case %d: %lld\n", ++cas, res);
}
 
void solve() {
    init();
    while (m--) {
        
        scanf("%d", &op);
        if (op == 4) {
            mp[1] ^= 1;
            mp[2] ^= 1;
            continue;
        }
        scanf("%d %d", &x, &y);
        if (op == 3) {
            exc(x, y);
        }
        else {
            insert(mp[op], x, y);
        }
    }
    print(mp[2]);
}
int _T;
int main() {
    while (~scanf("%d %d", &n, &m)) solve();
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值