Problem
acm.hdu.edu.cn/showproblem.php?pid=6206
Reference
计算几何求外心
三角形外心的坐标公式
20150_0907_三角形各种心的计算公式垂心外心重心内心
使用BigDecimal进行精确运算
Meaning
给出圆上三点 A、B、C 和另一个点 D 的坐标,问 D 是否在圆外。
Analysis
用 A、B、C 求出圆心 O(即三角形外心),然后用|OA|
和|OD|
的大小进行比较。精度问题,可以用 Java 的BigDecimal
。
Notes
- OJ 交 Java,类名是
Main
,不用(不能)写package
语句 - 用
Scanner
使读入比较方便 - 引入
Scanner
:import java.util.Scanner
- 用
Scanner
来包装System.in
:Scanner jin = new Scanner(System.in)
- 引入
BigDecimal
:import java.math.BigDecimal
BigDecimal
的加减乘除(BigDecimal x, y
):
x + y
:x.add(y)
x - y
:x.subtract(y)
x * y
:x.multiply(y)
x / y
:x.divide(y)
- 两个
BigDecimal
之间比较大小用compareTo()
,有三种返回值(x.compareTo(y)
):
-1
:x < y
0
:x = y
1
:x > y
Code
import java.util.Scanner;
import java.math.BigDecimal;
public class Main {
public static Scanner jin = new Scanner(System.in);
public static final BigDecimal two = new BigDecimal(2.0);
public static point circumcentre(point a, point b, point c) {
BigDecimal a1, a2, b1, b2, c1, c2, d, ox, oy;
// a1 = B.x - A.x
a1 = b.x.subtract(a.x);
// b1 = B.y - A.y
b1 = b.y.subtract(a.y);
// c1 = (a1 * a1 + b1 * b1) / 2
c1 = a1.multiply(a1).add(b1.multiply(b1)).divide(two);
// a2 = C.x - A.x
a2 = c.x.subtract(a.x);
// b2 = C.y - A.y
b2 = c.y.subtract(a.y);
// c2 = (a2 * a2 + b2 * b2) / 2
c2 = a2.multiply(a2).add(b2.multiply(b2)).divide(two);
// d = a1 * b2 - a2 * b1
d = a1.multiply(b2).subtract(a2.multiply(b1));
// ox = A.x + (c1 * b2 - c2 * b1) / d
ox = a.x.add(c1.multiply(b2).subtract(c2.multiply(b1)).divide(d));
// oy = A.y + (a1 * c2 - a2 * c1) / d
oy = a.y.add(a1.multiply(c2).subtract(a2.multiply(c1)).divide(d));
return new point(ox, oy);
}
public static BigDecimal dis(point a, point b) {
// (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)
return a.x.subtract(b.x).multiply(a.x.subtract(b.x)).
add(a.y.subtract(b.y).multiply(a.y.subtract(b.y)));
}
public static void main(String args[]) {
point O, A, B, C, D;
A = new point();
B = new point();
C = new point();
D = new point();
int T = jin.nextInt();
while(T-- > 0) {
// A (x1, y1)
A.x = jin.nextBigDecimal();
A.y = jin.nextBigDecimal();
// B (x2, y2)
B.x = jin.nextBigDecimal();
B.y = jin.nextBigDecimal();
// C (x3, y3)
C.x = jin.nextBigDecimal();
C.y = jin.nextBigDecimal();
// D (x, y)
D.x = jin.nextBigDecimal();
D.y = jin.nextBigDecimal();
O = circumcentre(A, B, C);
BigDecimal OA = dis(O, A);
BigDecimal OD = dis(O, D);
if(OD.compareTo(OA) != 1) // OD <= OA
System.out.println("Rejected");
else // OD > OA
System.out.println("Accepted");
}
jin.close();
}
}
class point {
public BigDecimal x, y;
public point() {}
public point(BigDecimal _x, BigDecimal _y) {
x = _x;
y = _y;
}
}