import java.util.; import java.io.; class Main { static final double eps = 1e-10; static int n; static Point[] P = new Point[10000 + 5]; static class Point { double x, y; int id; public Point() {} public Point(double x, double y, int id) { this.x = x; this.y = y; this.id = id; } } static int dcmp(double x) { if (Math.abs(x) < eps) return 0; return x < 0 ? -1 : 1; } static class Vector { double x, y; public Vector(double x, double y) { this.x = x; this.y = y; } } static Vector minus(Point A, Point B) { return new Vector(A.x - B.x, A.y - B.y); } static double Cross(Vector A, Vector B) { return A.x * B.y - A.y * B.x; } static boolean cmp(Point A, Point B) { return dcmp(Cross(minus(A, P[0]), minus(B, P[0]))) < 0; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { n = sc.nextInt(); P[0] = new Point(sc.nextDouble(), sc.nextDouble(), 1); for (int i = 1; i < n; ++i) { P[i] = new Point(sc.nextDouble(), sc.nextDouble(), i + 1); if (P[i].x < P[0].x || (P[i].x == P[0].x && P[i].y < P[0].y)) swap(P, 0, i); } Arrays.sort(P, 1, n, Main::cmp); System.out.println(P[0].id + " " + P[n / 2].id); } } static void swap(Point[] P, int i, int j) { Point temp = P[i]; P[i] = P[j]; P[j] = temp; } }解释这段代码的运行过程
时间: 2024-04-28 12:24:37 浏览: 102
该程序的功能是给定平面上的 n 个点,找出其中距离第一个点最近和最远的两个点,并输出它们的编号。
具体的运行过程如下:
1. 读入点的个数 n 和 n 个点的坐标信息,将第一个点设为 P[0]。
2. 对剩余的 n-1 个点进行排序,排序的基准是以第一个点 P[0] 为原点建立的极角排序。排序后,P[1] 是极角最小的点,P[n-1] 是极角最大的点。
3. 输出距离第一个点最近和最远的两个点的编号,分别是 P[0] 和 P[n/2]。
在排序时,程序使用了极角排序算法,即以一个点为原点,按照与该点的连线与 x 轴正半轴的夹角从小到大排序。排序算法的时间复杂度是 O(nlogn)。在排序完成后,程序只需要找到 P[0] 和 P[n/2] 这两个点即可,时间复杂度为 O(1)。
同时,程序还进行了一些简单的数学计算和数组操作,这些操作的时间复杂度是 O(n) 级别的,可以忽略不计。因此,总的时间复杂度为 O(nlogn)。
阅读全文