Commit 52959541 authored by Shiqing's avatar Shiqing
Browse files

Update non-traditional problems page

parent 04239d15
Loading
Loading
Loading
Loading
+42 −3
Original line number Diff line number Diff line
## 导语

我们知道,通过提交程序、由评测机输入数据并判断输出数据的题目叫传统题。而 OI 发展迅速,普通的传统题已经不能满足我们的所有需求,所以在近几年,有种非传统题慢慢进入大家的视野。
我们知道,通过提交程序、由评测机输入数据并判断输出数据的题目叫传统题。而 OI 发展迅速,普通的传统题已经不能满足我们的所有需求,所以在近几年,有种非传统题慢慢进入大家的视野。

## 提交答案题

@@ -13,6 +13,45 @@

## 交互题

交互题会有另一个题目自带程序(或者你的程序中评测器添加的非选手代码部分)和你的代码一起交互、一起运行,并不像以前一样只有你自己的程序在运行。你可以看看 [UOJ #206. 【APIO2016】Gap](http://uoj.ac/problem/206) 了解一下交互题
交互题中,选手程序需要通过与测评程序交互来完成任务。一类常见的情形是,选手程序向测评程序发出询问,并得到其反馈。测评程序可能对选手的询问作出限制,或调整应答策略来尽可能增加询问次数,这也给题目带来了更多变化

交互题一般会给你一个头文件,让你 `include` 它。这种题要求你实现一个函数,在评测时,评测工具就会调用这个函数。有时还会给你一些系统自带的辅助函数帮助你做题。
交互方式主要有如下两种。虽然技术上有不小的差异,但在考察算法的本质上它们并没有实际区别。

### STDIO 交互

STDIO 交互(标准 I/O 交互)是 Codeforces、AtCoder 等在线平台的交互手段,也是 ICPC 系列赛事中的标准。[LOJ #559. 「LibreOJ Round #9」ZQC 的迷宫](https://loj.ac/problem/559) 是一道典型的 STDIO 交互题。[这里](https://codeforces.com/blog/entry/45307) 是 Codeforces 的一个更加简要的说明。

对于这类题目,选手只需像往常一样将询问写到标准输出,**刷新输出缓冲**后从标准输入读取结果。选手程序刷新输出缓冲后,通过管道连接它的测评程序(称为交互器)才能立刻接收到这些数据。在 C/C++ 中,`fflush(stdout)``std::cout << std::flush` 可以实现这个操作;Pascal 则是 `flush(output)`

### Grader 交互

Grader 交互方式常见于 IOI、APIO 等国际 OI 赛事(特别是 CMS 平台的竞赛)。[UOJ #206. 【APIO2016】Gap](http://uoj.ac/problem/206) 是一道典型的 grader 交互题。

对于这类题目,选手只需编写一个特定的函数完成某项任务,它通过调用给定的若干辅助函数来进行交互。为了便于选手在本地测试,题目会下发一个头文件与一个参考测评程序 `grader.cpp`(对于 Pascal 语言是一个库 `graderlib`),选手将自己的程序与 `grader.cpp` 一同编译方可得到可执行文件。

```sh
g++ grader.cpp my_solution.cpp -o my_solution -Wall -O2
./my_solution   # 执行程序
```

编译得到的程序表现与传统题程序类似。它会打开固定的文件,以固定的格式读取数据,调用选手编写的函数,并将结果和若干信息(例如询问的次数、答案正确性)显示在标准输出上。

实际测评时,选手的程序会与一个不同的 `grader.cpp` 编译。这个 `grader.cpp` 将以类似的方式调用选手编写的函数,并记录其得分。一般来说,这个版本的 `grader.cpp` 所有全局符号都会设为 `static`,也即不能通过冲突命名的方式破解它,但是任何尝试突破 grader 限制的行为都是会导致 disqualification 的哦。

### 差别

STDIO 交互的一个明显优势在于它可以支持任何编程语言,但是输入输出的耗时容易成为问题设计的瓶颈,导致有时无法区分程序的时间效率差别。而 grader 交互则恰好相反,由于函数调用的开销不大,常常可以允许 $10^6$ 数量级的询问次数,但是语言的限制是其短板。

如果自己设计题目或举办比赛,就要记得权衡这些啦。

## 通信题

在通信题中,选手需要编写**两个**程序,合作完成某项任务。第一个程序接收问题的输入,并产生某些输出;第二个程序的输入会与第一个的输出相关(有时是原封不动地作为一个参数,有时是受到扰动,也有许多种其他变化),它需要产生问题的解。[UOJ #178. 新年的贺电](http://uoj.ac/problem/178)[#454. 【UER #8】打雪仗](http://uoj.ac/problem/454) 都是典型的通信题。

本地测试的方法由于题目设定的不同而多种多样,常用的如:

* 手工输入
* 编写一个辅助程序,转换第一个程序的输出到第二个程序的输入
* 用双向管道将两个程序的标准输入/输出连接起来

由于评测平台对于通信题的支持有限,因而目前为止通信题只常见于 IOI 系列赛和 UOJ 等少数在线平台举办的比赛,仍是一个有待探索的领域。期待着在未来,通信题能带来更多全新的挑战和新鲜的 idea。