政府决定修建一个穿过 $N$ 个城市的全新公路网。每个城市都已经指定了其枢纽(junction)的期望位置。政府的政策规定,公路只能沿直线修建。令人惊奇的是,两条公路就足以连接所有的城市,也就是说,可以确定两条直线,使得每个枢纽点都位于这两条直线之一上。此外,这两条直线都各自包含至少三个枢纽,并且两条直线的交点处没有枢纽。很容易证明,在这些条件下,这两条直线是唯一确定的。你们公司的任务是修建这个公路网,因此你们需要知道这两条直线的轨迹。枢纽点的坐标已在土地管理局(Land Office)登记,但你只被允许向该局提交查询,询问给定的某三个枢纽点是否共线。由于每次查询都需要支付高额的手续费(你懂的,那些官僚……),你的目标是尽可能减少查询次数。
由于两个枢纽点可以完全确定一条直线的轨迹,你的任务是为这两条直线中的每一条确定两个枢纽点。
任务
你需要编写一个程序,用尽可能少的查询次数,确定两条公路上各自的两个枢纽。
交互库
为了进行查询,你被提供了一个名为 office 的交互库,它包含以下三个操作:
GetN:在程序开始时调用一次,无参数;它返回城市数量 $N$。对应的枢纽编号为 $1$ 到 $N$。isOnLine:调用时需传入三个枢纽的编号作为参数。isOnLine(x, y, z)在枢纽点 $x$、$y$ 和 $z$ 共线时返回 $1$,否则返回 $0$。注意,任意两个点总是共线的。Answer:在程序结束时调用一次;它提交你的答案并正常终止程序的运行。Answer有四个整型参数:a1、b1、a2、b2。其中a1和b1是其中一条公路上的两个枢纽,a2和b2是另一条公路上的两个枢纽。
Pascal 程序员指南:在你的源代码中包含导入语句:
uses office;
C/C++ 程序员指南:使用以下指令:
#include "office.h"
测试
你可以从竞赛系统中下载 sample.zip,其中包含了交互库 office 的一个实现源码。该交互库从标准输入读取数据。第一行必须包含一个整数,即城市数量。第二行必须包含空格分隔的整数,表示第一条公路上的枢纽编号。第二条公路上的枢纽即为未在第二行中列出的所有枢纽。
数据范围
对于城市数量 $N$,我们有 $40 \le N \le 100\,000$。
Pascal 函数声明:
function GetN: longint; function isOnLine(x, y, z: longint): integer; procedure Answer(a1, b1, a2, b2: longint);C/C++ 函数声明:
int GetN(void); int isOnLine(int x, int y, int z); void Answer(int a1, int b1, int a2, int b2);你的程序不得读写任何文件,包括标准输入和输出。
子任务与评分
评分程序(grader)不使用预先确定的场景,但它会在不自相矛盾的前提下回答查询。只有当你的程序之前进行的查询能够推导出你的答案时,你的答案才会被接受。(因此,猜测是没有意义的。)
本题共有 25 个测试点。如果你的答案正确,且你的程序进行的查询次数为 $K$,则你的得分如下:
若 $K \le N/2 + 2$,得 4 分;
否则,若 $K \le 2N/3$,得 2 分;
否则,若 $K \le N - 3$,得 1 分;
否则,得 0 分。
你可以认为评分程序回答查询的方式会使得你的程序在进行少于 $N/3$ 次查询时无法给出正确答案。