色球 (Nowcoder)

题目

n个位置,m个操作。操作1,把x个颜色为y的球放到z位置的顶部;操作2,从z位置顶部取出x个球,输出最后一个球的颜色;操作3,把位置u的球倒过来放到位置v顶部。

题解&&思路:

2020CSP-S前的最后一篇题解:

这道题其实是用来自己学习双向链表的,因为之前从没有学过链表(可为什么会写链式前向星),所以借此来学习一下

听大家说,如果学过双向链表,就是一道水题了。

其实双向链表就是要记住一下每个点的前驱与后继,然后对于一类的点要记住它的head与tail即可

知道了这一点,其实这道题就可以直接用双向链表直接搞即可

首先操作1就直接insert,操作2是可以暴力的,操作3因为需要反转,所以这里其实不需要管谁是前驱谁是后继,因为如果每一次都是从最后推前面,因此最后一个点确定,上一个点也确定了,则递推即可

代码

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 3;
int n , m;
struct node{
    int num , col , ch[2];//ch记的是前驱或后继
    node(){}
    node( int N , int C , int CH1 , int CH2 ){
        num = N , col = C , ch[0] = CH1 , ch[1] = CH2;
    }
}a[MAXN];
int ncnt , head[MAXN] , tail[MAXN];
int main(){
    scanf( "%d%d" , &n , &m );
    while( m -- ){
        int x ,y;
        char s[6];scanf( "%s" , s);scanf( "%d%d" , &x , &y );
        if( s[2] == 's' ){
            int z;scanf( "%d" , &z );
            a[++ncnt] = node( x , y , tail[z] , 0 );
            if( tail[z] ){
                if( a[tail[z]].ch[0] ) a[tail[z]].ch[1] = ncnt;
                else a[tail[z]].ch[0] = ncnt;
            }
            else head[z] = ncnt;
            tail[z] = ncnt;
        }
        else if( s[2] == 't' ){
            if( !tail[x] ) continue;
            if( tail[y] ){
                if( a[tail[y]].ch[0] ) a[tail[y]].ch[1] = tail[x];
                else a[tail[y]].ch[0] = tail[x];
                if( a[tail[x]].ch[0] )  a[tail[x]].ch[1] = tail[y];
                else a[tail[x]].ch[0] = tail[y];
            }
            else{
                head[y] = tail[x];
            }
            tail[y] = head[x];
            head[x] = tail[x] = 0;
        }
        else{
            while( x > a[tail[y]].num ){
                x -= a[tail[y]].num;
                int last;
                if( a[tail[y]].ch[0] ) last = a[tail[y]].ch[0];
                else last = a[tail[y]].ch[1];
                if( a[last].ch[0] == tail[y] ) a[last].ch[0] = 0;
                else a[last].ch[1] = 0;
                tail[y] = last;
            }
            a[tail[y]].num -= x;
            printf( "%d\n" , a[tail[y]].col );
        }
    }
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值