湖南程序设计真题 一行盒子 (链表模拟)


一行盒子

 

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

l 1 X Y表示把盒子X移动到盒子Y左边(如果X已经在Y的左边则忽略此指令)。

l 2 X Y表示把盒子X移动到盒子Y右边(如果X已经在Y的右边则忽略此指令)。

l 3 X Y表示交换盒子XY的位置。

l 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组数据,每组数据第一行为盒子个数n和指令条数m1<=n,m<=100,000),以下m行每行包含一条指令。

 

输出

每组数据输出一行,即所有奇数位置的盒子编号之和。位置从左到右编号为1~n

 

样例输入


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



样例输出

Case 1: 12

Case 2: 9

Case 3: 2500050000



水题,写三个函数水过。



#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;
//freopen("b.in","r",stdin);
    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;
        __int64 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+=(__int64)p->n;
        }
        printf("Case %d: %I64d\n",tt++,ans);
        free(p);
        free(pre);
        free(phead);
    }




    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值