P11979 [KTSC 2021] 射击游戏 / gun

题目背景

本题翻译自 [2021년도 국제정보올림피아드 대표학생 선발고사](https://www.ioikorea.or.kr/archives/ioitst/2021/) 2차 선발고사 [#1 총 쏘기](https://assets.ioikorea.or.kr/ioitst/2021/2/gun/gun_statement.pdf)。 **请注意,你不需要也不应该实现 `main` 函数。具体实现方式见【实现细节】部分。** **警告:滥用本题评测一次即可封号。**

题目描述

有一款由两名玩家共同参与的在线射击游戏。游戏的目标是在一个虚构的城市中摧毁建筑物。 游戏中,$N$ 座建筑物从左到右排列在水平地面上。建筑物从左到右依次编号为 $1$ 到 $N$。每座建筑物的高度用一个序列 $A_i$($1 \leq i \leq N$)表示,且 $A_i$ 是 $1$ 到 $N$ 之间互不相同的整数。 两名玩家从所有建筑物左侧的同一位置出发。在时间 $i$($i \geq 1$)时,两名玩家同时发射一发子弹,子弹从发射位置水平向右飞行。两发子弹的速度相同。玩家可以选择子弹的发射高度 $H$,即从地面到子弹的垂直距离,$H$ 为 $1$ 到 $N + 1$ 之间的整数。两名玩家可以选择相同的发射高度。 如果玩家选择的发射高度为 $H$,则子弹会摧毁满足 $A_i \geq H$ 且未被摧毁的最左侧建筑物。如果没有满足条件的建筑物,则不会发生任何事。如果两名玩家的子弹同时满足条件且目标建筑物相同(由于子弹速度相同),则只有该建筑物会被摧毁。特别地,如果两名玩家的发射高度相同,则始终只有一个建筑物被摧毁。例如,若 $A_1 = 2$,$A_2 = 1$,且两名玩家均选择 $H = 1$,则只有建筑物 $1$ 会被摧毁。 问题的目标是:给定 $N$ 座建筑物的高度,找到摧毁所有建筑物的最短时间 $S$,以及每个时间点两名玩家的子弹发射高度。 ### 实现细节 你需要实现以下函数: ```cpp vector< pair > min_shooting_buildings(vector A) ``` - 该函数仅被调用一次。 - 参数 $A$ 是一个长度为 $N$ 的数组,$A[i]$ 表示建筑物 $i + 1$ 的高度 $A_{i+1}$($0 \leq i \leq N - 1$)。 - 该函数返回一个长度为 $S$ 的数组 $M$,其中 $S$ 是摧毁所有建筑物的最短时间。数组 $M$ 的每个元素 $(a, b)$ 表示两名玩家的子弹发射高度。 在提交的源代码中,任何地方都不允许调用输入输出函数。

输入格式

示例评分程序的输入格式如下: - 第 $1$ 行:$N$ - 第 $2$ 行:$A[0] \ A[1] \ \cdots \ A[N - 1]$

输出格式

示例评分程序的输出格式如下: - 第 $i$ 行($1 \leq i \leq S$):函数 `min_shooting_buildings` 返回的数组的第 $i$ 个元素。 注意:示例评分程序可能与实际评分程序不同。

说明/提示

### 约束条件 - $1 \leq N \leq 100\,000$ - $1 \leq A_i \leq N$($1 \leq i \leq N$) - $A_i$($1 \leq i \leq N$)互不相同。 ### 子任务 1. ($17$ 分) - 不存在 $1 \leq i < j < k \leq N$ 满足 $A_i < A_j < A_k$。 2. ($12$ 分) - 不存在 $1 \leq i < j < k \leq N$ 满足 $A_i > A_j > A_k$。 3. ($9$ 分) - $N \leq 4$。 4. ($12$ 分) - $N \leq 16$。 5. ($31$ 分) - $N \leq 500$。 6. ($29$ 分) - $N \leq 7\,500$。 7. ($40$ 分) - 无额外约束。 ### 评分标准 如果函数 `min_shooting_buildings` 返回的数组长度 $S$ 为摧毁所有建筑物的最短时间,且按返回的数组发射子弹能摧毁所有建筑物,则该测试用例视为正确。 ### 示例 - 示例 1:$N = 4$,$A = [1, 2, 4, 3]$。 调用函数: ```cpp min_shooting_buildings([1, 2, 4, 3])` ``` 如图 1 所示,若两名玩家按 $(1, 2), (3, 4), (3, 3)$ 发射子弹,可在时间$3$摧毁所有建筑物。 ![图 1](https://cdn.luogu.com.cn/upload/image_hosting/wwnh5752.png) 如图 2 所示,若按 $(1, 4), (2, 3)$ 发射子弹,可在时间 $2$ 摧毁所有建筑物。 ![图 2](https://cdn.luogu.com.cn/upload/image_hosting/ytj003m6.png) 因此,函数应返回长度为 $2$ 的数组,例如 `[(1, 4), (2, 3)]`。 - 示例 2:$N = 8$,$A = [4, 3, 8, 2, 1, 7, 6, 5]$。 函数应返回长度为 $4$ 的数组,例如 `[(4, 8), (3, 7), (2, 6), (1, 5)]`。 - 示例 3:$N = 8$,$A = [5, 6, 7, 1, 2, 8, 3, 4]$。 函数应返回长度为 $4$ 的数组,例如 `[(5, 6), (7, 8), (1, 2), (3, 4)]`。