/**
1. 斜率最大的点对 -> 斜率k = (y2 - y1) / (xz - x1) , 找到2个点x距离最小, y距离最大, 可以先按x从小到大排序
2. 排序后 对于任意点point[i], 那么x差值最小的点是point[i+1] 和 point[i-1] , 从前向后遍历可省去point[i-1]
3. 但是这样的点的y值是无法确定的, 我们可以观察下相邻3个点的关系, 可以发现:
3.1 3个点point[i], point[i+1], point[i+2]在一条直线上时,斜率相等
3.2 point[i+1] 在其余两个点上方时: k(i , i+1) > k(i, i+2) > k(i+1, i+2)
3.3 point[i+1] 在其余两个点下方时: k(i+1, i+2) > k(i, i+2) > k(i , i+1)
所以结果必定在相邻两个点之间才能取到最大值, 复杂度为O(nlogn)
4. 因为输出所有斜率最大的点, 要把相邻的在最大斜率上的点缓存下来分别输出, 当所有点对斜率都相等时, 输出的复杂度为O(n^2)
*/
import java.util.*;
public class Main
{
class Point{
int x, y, index;
public Point(int x, int y, int index){
this.x = x;
this.y = y;
this.index = index;
}
}
void run(){
int n = jin.nextInt();
List<Point> list = new ArrayList<>();
for (int i= 0 ; i < n ; i++) list.add(new Point(jin.nextInt(), jin.nextInt(), i+1));
list.sort((a,b)->(a.x-b.x));
double maxK = Double.MIN_VALUE;
for (int i = 0 ; i < n - 1; i ++){
Point cur = list.get(i);
Point next = list.get(i+1);
double k = 1.0 * (next.y - cur.y) / (next.x - cur.x);
maxK = Math.max(maxK, k);
}
List<Point> buffer = new ArrayList<>();
for (int i = 0; i< n-1 ; i++){
Point cur = list.get(i);
Point next = list.get(i+1);
double k = 1.0 * (next.y - cur.y) / (next.x - cur.x);
buffer.add(cur);
if (i == n-2 && k == maxK) buffer.add(next);
if (k != maxK) print(buffer);
}
print(buffer);
}
void print(List<Point> buffer){
for (int u = 0 ; u < buffer.size(); u++)
for (int v = u + 1; v < buffer.size(); v++)
System.out.printf("%d %d\n", buffer.get(u).index, buffer.get(v).index);
buffer.clear();
}
private Scanner jin = new Scanner(System.in);
public static void main(String[] args){
new Main().run();
}
}