湖南省第九届大学生计算机程序设计竞赛 G - 一行盒子

 G - 一行盒子

你有一行盒子,从左到右依次编号为1, 2, 3,…, n。你可以执行四种指令:

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。

Input

输入包含不超过10组数据,每组数据第一行为盒子个数n和指令条数m(1<=n,m<=100,000),以下m行每行包含一条指令。

Output

每组数据输出一行,即所有奇数位置的盒子编号之和。位置从左到右编号为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: 12Case 2: 9Case 3: 2500050000
Hint
代码:
#include <iostream>
#include<stdio.h>
#include<string.h>
#include <algorithm>
#include <queue>
#include <queue>
#include <map>
#define MAXN 100005
using namespace std;
struct link{
    int n;
    struct link *nex;
    struct link *pre;
};
int n,m;
link *has[110000];
//x移到y左边
void move1(int x,int y) {
    (has[x]->pre)->nex=(has[x]->nex);
    (has[x]->nex)->pre=has[x]->pre;




    has[x]->nex = has[y];
    has[x]->pre = has[y]->pre;
    (has[y]->pre)->nex=has[x];
    has[y]->pre = has[x];
}


//x移到y右边
void move2(int x,int y) {
    (has[x]->pre)->nex=(has[x]->nex);
    (has[x]->nex)->pre=has[x]->pre;//删除x结点








    has[x]->nex = has[y]->nex;
    has[x]->pre = has[y];
    (has[y]->nex)->pre=has[x];
    has[y]->nex = has[x];
}


//交换x和y
void exchange(int x,int y) {
    has[x]->n=y;
    has[y]->n=x;




    link *h;
    h=has[x];
    has[x]=has[y];
    has[y]=h;
}
int main()
{
    int tt=1,flag;
    while (scanf("%d %d",&n,&m)!=EOF)
    {
        struct link* p,*pre,*phead = NULL;
        phead = (link*)malloc(sizeof(link));
        pre = phead;
        for (int i=1; i<=n+1; i++)
        {
            p =(link*)malloc(sizeof(link));
            p->n = i;
            has[i]=p;
            p->pre = pre;
            pre->nex = p;
            pre=p;
            if (i==n+1)
                p->nex = NULL;
        }
        p = phead;




        int k,a,b;
        flag = 1;
        while (m--)
        {
            scanf("%d",&k);
            if (k==4)
            {
                flag*=-1;
            }
            else
            {
                scanf("%d %d",&a,&b);
                if(k==1&&flag==1)
                    move1(a,b);
                else if(k==1&&flag==-1)
                    move2(a,b);
                else if(k==2&&flag==1)
                    move2(a,b);
                else if(k==2&&flag==-1)
                    move1(a,b);
                else if(k==3)
                    exchange(a,b);
            }
        }
        p = phead;
        int o;
        long long ans=0;
        if(n%2==0&&flag==-1)
            o=0;
        else o=1;
        int num=0;
        while (p->nex!=NULL&&p->nex->n<=n)
        {
            p=p->nex;
            num++;
            //  printf("%d\n",p->n);
            if(num%2==o)
                ans+=(long long)p->n;
        }
        printf("Case %d: %lld\n",tt++,ans);
        free(p);
        free(pre);
        free(phead);
    }
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值