洛谷题解:B4194 [海淀区小学组 2023] 生日

题目传送门。

题意


题目给出了一个长度为 n n n 的数组,要求我们构造一个数组的排序,这个排序要使这个数组每个数之间的差的绝对值最大值最小(包括第 1 1 1 个和第 n n n 个,即一个环)。

分析


这道题从哪里入手呢?首先观察样例。

输入:
5
2 1 1 3 2
输出:
1 2 3 2 1

那么通过观察发现,想要得到我们想要的结果,构造数组时要尽可能让大的数在中间,越小的数尽量往两边散开,使两边平衡。

比如,这个答案数组中间的数 3 3 3,是原数组中最大的那个数,而 3 3 3 左边和右边都是对称的,这样使得它们的每个数之间的差的绝对值最大值最小(包括第 1 1 1 个和第 n n n 个,即一个环)。

分析完毕,来讲讲如何实现:

  • 我们先对数组进行从小到大的排序。

  • 用双指针,一个记录头,一个记录尾。

  • 将原数组的数交替存进答案数组的头和尾中。

  • 最后记得特判一下 n n n 为奇数的情况,那么答案数组中间的那个数就是原数组最大的那个数。

这个思路能够直接在 5 × 1 0 6 5 \times 10^6 5×106 下通过,可以不需要优化输入输出速度。不过在赛场上容易卡常,建议使用 scanf();printf();ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 优化输出。

Code


// B4194.[海淀区小学组 2023] 生日
#include <cstdio>
#include <algorithm>
#define N 5000005
using namespace std;
int n, h, t, a[N], ans[N];
int main() {
	scanf ("%d", &n);
	for (int i = 1; i <= n; i++) scanf ("%d", &a[i]);
	// 对数组进行排序 
	sort (a + 1, a + 1 + n);
	t = n;
	for (int i = 1; i <= n; i += 2) {
		// 开始一头一尾重置新数组 
		ans[++h] = a[i];
		ans[t--] = a[i + 1];
	}
	// 特判奇数个数的情况:新数组最中间的数是原数组最后一个数 
	if (n % 2 == 1) ans[h] = a[n];
	for (int i = 1; i <= n; i++) printf ("%d ", ans[i]);
	return 0;
}

完结撒花。

AC 记录。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值