E. [Sleeping Cup #11] Topology-Aware Step-By-Step Sorting

    传统题 1000ms 512MiB

[Sleeping Cup #11] Topology-Aware Step-By-Step Sorting

该比赛已结束,您无法在比赛模式下递交该题目。您可以点击“在题库中打开”以普通模式查看和递交本题。

注意

本题是交互题,请严格按照提交方式进行操作。

本题的交互库不是自适应的,排列 p\bm p 在交互开始前已经预先确定,不会在交互过程中动态改变。

请不要实施自行处理输入输出(除了标准错误流 stderr),强制退出(如调用 exit 或 quick_exit 函数),攻击交互库等可能扰乱比赛秩序的行为,否则按作弊处理。

本题的原始数据没有针对任何随机数生成器或随机数种子进行特定构造,但接受基于随机数生成器攻击的 hack 数据。如果需要使用随机数,请使用难以预测的随机数种子(如使用 <random> 头文件中的 std::random_device 类随机数生成器生成,先定义该类型的随机数生成器 rd,然后使用 rd() 作为随机数种子),以免赛后被 hack。

题目描述

交互库有一个 1,2,…,10001, 2, \ldots, 1000 的排列 pp 并拒绝让你直接访问。

你被允许做如下操作,次数不限:

  • 向交互库支付 C=max⁡{I2−I1,0}+1C = \max\{I_2 - I_1, 0\} + 1 个金币,交换 pp 中你所指定的两项,其中:
    • I1I_1 是操作前 pp 中逆序对的数量。
    • I2I_2 是操作后 pp 中逆序对的数量。
  • 操作结束后,交互库会给你结账,告知你 CC 的值。

你的手里有 5×1045 \times 10^4 个金币,请在不欠债的前提下将 pp 重排成升序 {1,2,…,1000}\{1, 2, \ldots, 1000\}。

交互方式

本题是交互题。

本题提供额外头文件 "sorting.h",你需要使用它进行交互:

函数 描述 限制 可调用次数
int operate\\(int l, int r); 交换排列的第 ll 项和第 rr 项\\并得到 CC 的值 1≤l<r≤10001 \le l < r \le 1000 不限
void confirm(); 当你认为完成了排序时,\\告知交互库排序完成 你必须在告知后\\终止程序 11

请在以下模板上答题。

#include <bits/stdc++.h>
#include "sorting.h"
using namespace std;
int main()
{
	int n = 1000, q = 5e4;
	bool ok = false;
	while (!ok)
	{
		int l = 1, r = n;
		// ...
		int c = operate(l, r);
		q -= c;
		assert(q >= 0);
		// ...
	}
	confirm();
	return 0;
}

下发文件

请在这里下载下发文件。

我们下发了示例头文件 sorting.h 和两个样例(1.in 和 2.in),该头文件和实际评测时使用的头文件实现基本一致,但实际评测时使用的头文件添加了用于抵御非法攻击的特殊模块。

请将你的程序 sorting.cpp 和头文件 sorting.h 放在同一目录下后,使用以下命令编译得到可执行文件(<Additional Parameters...> 是你自己指定的额外编译参数,Windows 下得到 sorting.exe,Linux 下得到 sorting):

g++ sorting.cpp -o sorting <Additional Parameters...>

然后把样例 1 1.in 放在同一目录下,使用以下命令让程序从标准输入 stdin 读入并测试样例:

  • sorting < 1.in(Windows)
  • ./sorting < 1.in(Linux)

样例 2 2.in 的测试方式同理。

程序将向标准输出 stdout 打印评测结果,保证打印的信息与评测时返回的信息一致。

你也可以自己将一行 10001000 个空格隔开的正整数(必须是一个 1,2,…,10001, 2, \ldots, 1000 的排列)写入文件,把它放在同一目录下,使用和上面类似的方式测试。

请注意,头文件不会校验输入的合法性。

样例 1

测试点 1 和下发的 1.in 使用与本样例相同的秘密排列进行评测。

以下的交互过程可以获得 AC。

调用函数 返回值 解释
operate(1, 2); 22 这表明 p1<p2p_1 < p_2
11 把它换回去
operate(2, 3); 22 这表明 p2<p3p_2 < p_3
11 把它换回去
(此处省略 19921992 次类似的函数调用)
operate(999, 1000); 22 这表明 p999<p1000p_{999} < p_{1000}
11 把它换回去
(由上可知,原来的排列就是 {1,2,…,1000}\{1, 2, \ldots, 1000\})
confirm(); // 一共支付了 29972997 枚金币,答案正确

样例 2

测试点 2 和下发的 2.in 使用与本样例相同的秘密排列进行评测。

以下的交互过程可以获得 AC。

调用函数 返回值 解释
operate(1, 2); 11 这表明 p1>p2p_1 > p_2
22 把它换回去
operate(2, 3); 11 这表明 p2>p3p_2 > p_3
22 把它换回去
(此处省略 19921992 次类似的函数调用)
operate(999, 1000); 11 这表明 p999>p1000p_{999} > p_{1000}
22 把它换回去
(由上可知,原来的排列就是 {1000,999,…,1}\{1000, 999, \ldots, 1\})
operate(1, 1000); 11 将 p1p_1 和 p1000p_{1000} 归位
operate(2, 999); 将 p2p_2 和 p999p_{999} 归位
(此处省略 497497 次类似的函数调用)
operate(500, 501); 11 将 p500p_{500} 和 p501p_{501} 归位
confirm(); // 一共支付了 34973497 枚金币,答案正确

Sleeping Cup #11

未参加
状态
已结束
规则
Sleeping Cup
题目
7
开始于
2026-6-6 0:00
结束于
2026-7-20 0:00
持续时间
2 小时
主持人
参赛人数
20