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龙珠的主要内容,如果未能解决你的问题,请参考以下文章
luogu P4513ybtoj线段树课堂过关例题3小白逛公园