|
|
|
|
package class50;
|
|
|
|
|
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
|
|
|
|
|
public class Problem_0587_ErectTheFence {
|
|
|
|
|
|
|
|
|
|
public static int[][] outerTrees(int[][] points) {
|
|
|
|
|
int n = points.length;
|
|
|
|
|
int s = 0;
|
|
|
|
|
int[][] stack = new int[n << 1][];
|
|
|
|
|
// x小的排前面,x一样的,y小的排前面
|
|
|
|
|
Arrays.sort(points, (a, b) -> a[0] != b[0] ? a[0] - b[0] : a[1] - b[1]);
|
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
|
while (s > 1 && cross(stack[s - 2], stack[s - 1], points[i]) > 0) {
|
|
|
|
|
s--;
|
|
|
|
|
}
|
|
|
|
|
stack[s++] = points[i];
|
|
|
|
|
}
|
|
|
|
|
for (int i = n - 2; i >= 0; i--) {
|
|
|
|
|
while (s > 1 && cross(stack[s - 2], stack[s - 1], points[i]) > 0) {
|
|
|
|
|
s--;
|
|
|
|
|
}
|
|
|
|
|
stack[s++] = points[i];
|
|
|
|
|
}
|
|
|
|
|
// 去重返回
|
|
|
|
|
Arrays.sort(stack, 0, s, (a, b) -> b[0] == a[0] ? b[1] - a[1] : b[0] - a[0]);
|
|
|
|
|
n = 1;
|
|
|
|
|
for (int i = 1; i < s; i++) {
|
|
|
|
|
// 如果i点,x和y,与i-1点,x和y都一样
|
|
|
|
|
// i点与i-1点,在同一个位置,此时,i点不保留
|
|
|
|
|
if (stack[i][0] != stack[i - 1][0] || stack[i][1] != stack[i - 1][1]) {
|
|
|
|
|
stack[n++] = stack[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return Arrays.copyOf(stack, n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 叉乘的实现
|
|
|
|
|
// 假设有a、b、c三个点,并且给出每个点的(x,y)位置
|
|
|
|
|
// 从a到c的向量,在从a到b的向量的哪一侧?
|
|
|
|
|
// 如果a到c的向量,在从a到b的向量右侧,返回正数
|
|
|
|
|
// 如果a到c的向量,在从a到b的向量左侧,返回负数
|
|
|
|
|
// 如果a到c的向量,和从a到b的向量重合,返回0
|
|
|
|
|
public static int cross(int[] a, int[] b, int[] c) {
|
|
|
|
|
return (b[1] - a[1]) * (c[0] - b[0]) - (b[0] - a[0]) * (c[1] - b[1]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
int[] a = { 4, 4 };
|
|
|
|
|
int[] b = { 1, 1 };
|
|
|
|
|
int[] c = { 1, 5 };
|
|
|
|
|
System.out.println(cross(a, b, c));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|