HDU 6206 Apple ( 高精度 && 计算几何 && 三点构圆求圆心半径 )

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 6206 Apple ( 高精度 && 计算几何 && 三点构圆求圆心半径 )相关的知识,希望对你有一定的参考价值。

题意 : 给出四个点,问你第四个点是否在前三个点构成的圆内,若在圆外输出"Accepted",否则输出"Rejected",题目保证前三个点不在一条直线上。

 

分析 : 简单的计算几何问题,如果能够知道圆心和半径(Radius)以及第四个点和圆心的距离(Distance),我们就能够判断第四个点是否在圆外,例如Distance > Radius则在圆外。三点构圆 的圆心和半径是能够推导出公式的

(参考==> http://blog.csdn.net/death10001/article/details/77389128 )

设 技术分享 则有技术分享

根据两点间距离公式 R2 = (X - X0)2 + (Y - Y0)我们将刚刚的X0代数式和X(三个点的任何一个)代进去通分一下就能得到

[ 2*X*(bc-ad)+(de-bf) / 2(bc-ad) ]2 + [ 2*Y*(bc-ad)+(af-ce) / 2(bc-ad) ]2 

发现分母都是一样,可以通分。然后呢,还是根据两点间距我们可以用同样的方法得到第四个点和圆心之间的距离并且分母同样是2(bc-ad),所以运算的过程当中是不用进行除法操作的,只要比较两个分子即可,高精度问题也只用BigInteger解决即可。

 

技术分享
import java.util.Scanner;
import java.util.*;
import java.math.*;
import java.io.*;
class PO{ BigInteger x, y; }
public class Main{
    public static boolean Solve(PO p1, PO p2, PO p3, PO p){
        //-------------------------------------------------------------------------------------

        BigInteger a = p1.x.subtract(p2.x);
        BigInteger b = p1.y.subtract(p2.y);
        BigInteger c = p1.x.subtract(p3.x);
        BigInteger d = p1.y.subtract(p3.y);
        BigInteger e = (((p1.x).multiply(p1.x)).subtract((p2.x).multiply(p2.x))).subtract(((p2.y).multiply(p2.y)).subtract(((p1.y).multiply(p1.y))));
        BigInteger f = (((p1.x).multiply(p1.x)).subtract((p3.x).multiply(p3.x))).subtract(((p3.y).multiply(p3.y)).subtract(((p1.y).multiply(p1.y))));
        BigInteger two = new BigInteger("2");

        //-------------------------------------------------------------------------------------

        BigInteger tmp1 = (((p1.x).multiply((b.multiply(c)).subtract((a.multiply(d))))).multiply(two)).add((d.multiply(e)).subtract((b.multiply(f))));
        tmp1 = tmp1.multiply(tmp1);
        BigInteger tmp2 = (((p1.y).multiply((b.multiply(c)).subtract((a.multiply(d))))).multiply(two)).add((a.multiply(f)).subtract((c.multiply(e))));
        tmp2 = tmp2.multiply(tmp2);
        BigInteger R = tmp1.add(tmp2);///计算出半径的"长度" ( 实际是代数式的分子 )

        //-------------------------------------------------------------------------------------

        tmp1 = (((p.x).multiply((b.multiply(c)).subtract((a.multiply(d))))).multiply(two)).add((d.multiply(e)).subtract((b.multiply(f))));
        tmp1 = tmp1.multiply(tmp1);
        tmp2 = (((p.y).multiply((b.multiply(c)).subtract((a.multiply(d))))).multiply(two)).add((a.multiply(f)).subtract((c.multiply(e))));
        tmp2 = tmp2.multiply(tmp2);
        BigInteger Dis = tmp1.add(tmp2);///计算出圆心到第四个点的"距离"

        if(R.compareTo(Dis) < 0) return true;
        else return false;
    }
    public static void main (String[] args) throws Exception{
        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        int nCase = cin.nextInt();
        for(int t=1; t<=nCase; t++){
            PO p1 = new PO(); PO p2 = new PO();
            PO p3 = new PO(); PO aim= new PO();
            p1.x = cin.nextBigInteger(); p1.y = cin.nextBigInteger();
            p2.x = cin.nextBigInteger(); p2.y = cin.nextBigInteger();
            p3.x = cin.nextBigInteger(); p3.y = cin.nextBigInteger();
            aim.x = cin.nextBigInteger(); aim.y = cin.nextBigInteger();
            boolean res = Solve(p1, p2, p3, aim);
            if(res) System.out.println("Accepted");
            else System.out.println("Rejected");
        }
    }
}
View Code

 

瞎 : 实际上还有更简便的方法,直接能用更直接的公式算出圆心 (x0, y0) 和半径的平方 r^2

x0=((y2-y1)*(y3*y3-y1*y1+x3*x3-x1*x1)-(y3-y1)*(y2*y2-y1*y1+x2*x2-x1*x1))/(2.0*((x3-x1)*(y2-y1)-(x2-x1)*(y3-y1)));

y0=((x2-x1)*(x3*x3-x1*x1+y3*y3-y1*y1)-(x3-x1)*(x2*x2-x1*x1+y2*y2-y1*y1))/(2.0*((y3-y1)*(x2-x1)-(y2-y1)*(x3-x1)));

r^2=(x1-x0)*(x1-x0)+(y1-y0)*(y1-y0);

里面涉及除法,那就用BigDecimal就能解决了,参考 ==> http://blog.csdn.net/cillyb/article/details/78012069

以上是关于HDU 6206 Apple ( 高精度 && 计算几何 && 三点构圆求圆心半径 )的主要内容,如果未能解决你的问题,请参考以下文章

hdu 6206 apple 点在内接圆外

hdu6206 Apple 2017 ACM/ICPC Asia Regional Qingdao Online

poj 6206 Apple

HDU 1565&1569 方格取数系列(状压DP或者最大流)

noi 2.6_9288&hdu 1133Buy the Ticket(DP / 排列组合 Catalan+高精度)

HDU 5718 Oracle(高精度)