Educational Codeforces Round 2 D – Area of Two Circles’ Intersection
链接: http://codeforces.com/contest/600/problem/D
public class TaskD {
public void solve(int testNumber, InputReader in, OutputWriter out) {
double x1 = in.readDouble();
double y1 = in.readDouble();
double r1 = in.readDouble();
double x2 = in.readDouble();
double y2 = in.readDouble();
double r2 = in.readDouble();
MathContext mc = new MathContext(40, RoundingMode.HALF_UP);
//两圆,圆心距
BigDecimal c = BigDecimal.valueOf(Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)));
if (r1 + r2 <= c.doubleValue()) {
out.printFormat("%.20f\n", (double) 0.0);
return;
} //如果两圆不相交
else if (Math.abs(r2 - r1) >= c.doubleValue()) {
out.printFormat("%.20f\n", Math.PI * Math.pow(Math.min(r1, r2), 2)); // 面积是内圆的面积
return;
} else {
//1的圆心角
double r1_ang = Math.acos(BigDecimal.valueOf(r1).pow(2,mc).add(c.pow(2,mc)).subtract(BigDecimal.valueOf(r2).pow(2),mc).divide(BigDecimal.valueOf(2), 20, RoundingMode.CEILING).divide(BigDecimal.valueOf(r1),20, RoundingMode.CEILING).divide(c,20, RoundingMode.CEILING).doubleValue());
//2的圆心角
double r2_ang = Math.acos(BigDecimal.valueOf(r2).pow(2,mc).add(c.pow(2,mc)).subtract(BigDecimal.valueOf(r1).pow(2),mc).divide(BigDecimal.valueOf(2), 20, RoundingMode.CEILING).divide(BigDecimal.valueOf(r2),20, RoundingMode.CEILING).divide(c,20, RoundingMode.CEILING).doubleValue());
//1的面积
double a1 = r1_ang * Math.pow(r1, 2) - 0.5 * Math.pow(r1, 2) * Math.sin(r1_ang * 2);
//2的面积
double a2 = r2_ang * Math.pow(r2, 2) - 0.5 * Math.pow(r2, 2) * Math.sin(r2_ang * 2);
out.printFormat("%.20f\n", (a1 + a2));
}
}
}
这题不难,就是个公式, 但是Java的double不够精度, 需要用BigDecimal. 然而Java三角函数acos最多支持double, 不支持BigDecimal. 所以难点是要自己写acos(我是肯定不会写展开式的啊)…所以上面code是最高精度.
Btw, 我搜了所有code, 基本都是c++…..c++的long double还是好用啊
Leave A Comment