Educational Codeforces Round 2 D – Area of Two Circles’ Intersection
链接: http://codeforces.com/contest/600/problem/D
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
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