合肥市第38届信息学竞赛(2021年)整理书本(book)

题目描述 Description
又一个学期结束了,又积累了好多本书,你决定好好整理一下,整理时共有
三种操作,规则如下:
1,p 表示把编号为 p 的书放到最前面;
2,p 表示把编号为 p 的书放到最后面;
3,p q 表示把编号为 p 的书放到编号为 q 的书的后面;
1、2、3 分别代表整理操作的种类,p、q 表示书的编号,他们之间由空格分隔;已知在整理之前,所有书从 1 开始依次编号排放。

输入描述 Input Description
共 m+1 行。第一行有两个由空格分隔的正整数 n 和 m,分别表示 n 本书和 m 次整理操作,接下来 m 行,每行有 2 个或 3 个由空格分隔的正整数,对应上述三种整理操作。

输出描述 Output Description
共 1 行,经过整理后的书本顺序,书本间用空格隔开。

样例输入 Sample Input
10 4
1 3
2 4
3 3 6
3 1 5
样例输出 Sample Output
2 5 1 6 3 7 8 9 10 4
数据范围及提示 Data Size & Hint
数据范围:1≤n,m≤100000
本题不能使用模拟写法,会超时,得用模拟链表才不会超时
满分代码来了!!!

#include<iostream>
using namespace std;
int n,m,t,p,q;
int r[100005];//存第i个结点的后继地址
int l[100005];//存第i个结点的前驱地址

int main(){
    cin>>n>>m;
    r[0]=1;
    for(int i=1;i<=n;i++){
        r[i]=i+1;//第i个结点的后继地址
        l[i]=i-1;//第i个结点的前驱地址
    }
    l[n+1]=n;
    while(m--){
        cin>>t>>p;
        if(t==1){//表示把编号为p的书放到最前面;
            r[l[p]]=r[p];
            l[r[p]]=l[p];//删除结点p
            l[p]=0;
            r[p]=r[0];//插入结点p
            r[l[p]]=p;
            l[r[p]]=p;//连接结点p
        }else if(t==2){
            r[l[p]]=r[p];
            l[r[p]]=l[p];//删除结点p
            l[p]=l[n+1];
            r[p]=n+1;//插入结点p
            r[l[p]]=p;
            l[r[p]]=p;//连接结点p
        }else{
            cin>>q;
            if(p==q) continue;
            r[l[p]]=r[p];
            l[r[p]]=l[p];//删除结点p
            l[p]=q;
            r[p]=r[q];//插入结点p
            r[l[p]]=p;
            l[r[p]]=p;//连接结点p
        }
    }
    int idx=r[0];
    while(idx!=n+1){
        cout<<idx<<" ";
        idx=r[idx];
    }
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值