ybtoj 二叉堆课堂过关 例题3luogu 月赛 P5462指针龙珠游戏 & X龙珠

Posted SSL_ZZL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ybtoj 二叉堆课堂过关 例题3luogu 月赛 P5462指针龙珠游戏 & X龙珠相关的知识,希望对你有一定的参考价值。


Link

ybtoj【二叉堆课堂过关】【例题3】龙珠游戏
luogu 【月赛】【P5462】X龙珠
题面//因为不知道侵不侵权所以就是题面是私密的,有账号的直接看转送门就可了


题目大意

给出n,一个已给出顺序的1 ~ n的序列(给出顺序,不是递进顺序)
每次选中相邻的两个数,放入新的队列的尾端,最终会选出序列大小为n的队列
选出字典序最大的队列

输入输出样例

输入 #1

4 
3 1 4 2

输出 #1

4 2 3 1

输入 #2

6 
6 5 4 1 3 2

输出 #2

6 5 4 1 3 2

解题思路

first at all,我没用堆(然后我把它分到了数据结构,不知道算不算)

用(类似)指针的东西(?),指向前一个数和后一个数
每次尽量输出最大的数,每次输出后,维护指针指向(就是把断开的地方连上)
tips:很明显,如果最大的数在最后,就不能选(如果和前面的数一起选,那么也没有意义)

比如选中i,那么相邻的数last[i]也要选,中间与两边断开链接
把before[i] 和 last[last[i]] 连上

last[before[i]] = last[last[i]], before[last[last[i]]] = before[i];

Code

#include <iostream>
#include <cstdio>
#define N 100100

using namespace std;

int n, a[N], before[N], last[N];

int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; i ++) {
		scanf("%d", &a[i]);
		before[a[i]] = a[i - 1], last[a[i - 1]] = a[i];  //初始化指针
	}
	for(int i = n; i; i--) {
		if(!last[i]) continue;  //如果后面有链接,可以筛掉最后一个数 和 已经作为last[i']输出过的数
		printf("%d %d ", i, last[i]);
		last[before[i]] = last[last[i]],   //维护链接
		before[last[last[i]]] = before[i];
		last[last[i]] = 0;  //与两边断开断开链接
	}
} 

以上是关于ybtoj 二叉堆课堂过关 例题3luogu 月赛 P5462指针龙珠游戏 & X龙珠的主要内容,如果未能解决你的问题,请参考以下文章

ybtoj线段树课堂过关例题1求区间和

ybtoj背包问题课堂过关DP例题3宝物筛选

Ybtoj 树形DP课堂过关例题3最长距离

luogu P4513ybtoj线段树课堂过关例题3小白逛公园

ybtoj 单调队列课堂过关luogu P1886例题1滑动窗口

ybtoj树状数组课堂过关二维树状数组 例题5单点修改区间查询