算法竞赛入门经典第六章例题6-5 Boxes in a Line UVA - 12657

https://vjudge.net/problem/UVA-12657

A数组开始表示编号k的位置,后面表示最后编号的顺序

#include<iostream>
#include<cstring>
using namespace std;
#pragma warning(disable:4996)
struct node {
    int data;
    int l, r;
};
node all[100500];
bool _reverse=false;
int n, m, k;
int A[100500];
void one(int X, int Y) {
    if (all[Y].l == X) return;
    all[all[X].l].r = all[X].r, all[all[X].r].l = all[X].l;
    all[all[Y].l].r = X,all[X].l = all[Y].l;
    all[Y].l=X, all[X].r = Y;
}
void two(int X, int Y) {
    if (all[Y].r == X) return;
    all[all[X].l].r = all[X].r, all[all[X].r].l = all[X].l;
    all[all[Y].r].l = X,all[X].r = all[Y].r;
    all[Y].r=X, all[X].l = Y;
}

long long int Prin_sum() {
    long long int sum = 0,top=0,i;
    for (i = all[0].r; all[i].r != n + 2; i = all[i].r)
        A[++top] = all[i].data;
    i = (_reverse&& n % 2==0) ? 2 : 1;
    for (; i <= n; i += 2)
        sum += A[i];
    return sum;
}
int main() {
#ifdef _DEBUG
    freopen("in", "r", stdin);
    freopen("out", "wb", stdout); 
#endif // _DEBUG
    int X, Y,cnt=0,tt;
    while (cin>>n>>m) {
        all[0].r = 1; _reverse = false;
        for (int i = 1; i <= n + 1; ++i)//all[k].r==n+1表示结束
            all[i].l = i - 1, all[i].r = i + 1, all[i].data = i, A[i] = i;
        while (m--) {
            cin >> k;
            switch (k)
            {
            case 1:
                cin >> X >> Y; 
                    if (_reverse) two(A[X], A[Y]);
                    else one(A[X], A[Y]);
                    break;
            case 2:
                cin >> X >> Y;
                if (_reverse) one(A[X], A[Y]);
                else two(A[X], A[Y]);
                break;
            case 3:
                cin >> X >> Y;
                swap(all[A[X]].data, all[A[Y]].data);
                swap(A[X], A[Y]);
                break;
            case 4: _reverse = !_reverse;
                break;
            default:
                break;
            }
        }
        printf("Case %d: %lld\n", ++cnt, Prin_sum());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值