hdu 6206 模板题 2017 ACM/ICPC Asia Regional Qingdao Online

来源:互联网 发布:sql导入 powerdesigner 编辑:程序博客网 时间:2024/06/03 22:17

下面的模板来自于 

http://blog.csdn.net/liyuanbhu/article/details/52891868

三点确定一个圆的计算方法

最近在写的一个软件需要根据三个坐标点来计算一个圆。因此花了点时间推导了相关的公式。这个推导不算太难,放在这里主要是做个备忘。

我们设一个圆的圆心坐标为 (x0,y),半径为r。那么这个圆的方程可以写为:

(xx0)2+(yy0)2=r2

在这个圆上随便取三个点,设这三个点的坐标分别是 (x1,y1)(x2,y2)(x3,y3)。那么有:

(x1x0)2+(y1y0)2=r2(x2x0)2+(y2y0)2=r2(x3x0)2+(y3y0)2=r2(1)(2)(3)

公式(1)(2)相减,(1)(3)相减之后经过化简可以得到:

(x1x2)x0+(y1y2)y0=(x21x22)(y22y21)2(x1x3)x0+(y1y3)y0=(x21x23)(y23y21)2

x0,y0有唯一解的条件是系数行列式不为0

(x1x2)(x1x3)(y1y2)(y1y3)0

简单变变型也就是:

x1x2y1y2x1x3y1y3

这样写几何含义就很明显了,三点不能共线。

设:

a=x1x2b=y1y2c=x1x3d=y1y3e=(x21x22)(y22y21)2f=(x21x23)(y23y21)2

那么 :

x0=debfbcady0=afcebcad

有了 x0y0 的值后,带入(1) 式就可以得到 r的值。至此,三点确定圆的问题就解决了。

下面是个 C++ 代码(用到了Qt 的 QPointF 类型):

    #include <math.h>    #include <limits>    #include <QPoint>    #include <QDebug>    QPointF tcircle(QPointF pt1, QPointF pt2, QPointF pt3, double &radius)    {        double x1 = pt1.x(), x2 = pt2.x(), x3 = pt3.x();        double y1 = pt1.y(), y2 = pt2.y(), y3 = pt3.y();        double a = x1 - x2;        double b = y1 - y2;        double c = x1 - x3;        double d = y1 - y3;        double e = ((x1 * x1 - x2 * x2) + (y1 * y1 - y2 * y2)) / 2.0;        double f = ((x1 * x1 - x3 * x3) + (y1 * y1 - y3 * y3)) / 2.0;        double det = b * c - a * d;        if( fabs(det) < 1e-5)        {            radius = -1;            return QPointF(0,0);        }        double x0 = -(d * e - b * f) / det;        double y0 = -(a * f - c * e) / det;        radius = hypot(x1 - x0, y1 - y0);        return QPointF(x0, y0);    }


题意:

给出圆上三个点,然后请判断第四个点是否在这个圆内

题解:

先用C套一下模板,发现精度不够,然后翻译成java

在求距离的时候不用开平方,因为开平方的时候精度会损失


import java.math.BigDecimal;import java.math.BigInteger;import java.math.MathContext;import java.math.RoundingMode;import java.util.Scanner;import javax.security.auth.Subject;import javax.swing.ButtonGroup;public class Main {    static BigDecimal redius;    public static void main(String[] args) {        Scanner cin = new Scanner(System.in);        int t;        point a,b,c,d;        a = new point();        b = new point();        c = new point();        d = new point();        redius = new BigDecimal(0);        t = cin.nextInt();        while((t--)>0){            BigDecimal r;            a.x = cin.nextBigDecimal();            a.y = cin.nextBigDecimal();            b.x = cin.nextBigDecimal();            b.y = cin.nextBigDecimal();            c.x = cin.nextBigDecimal();            c.y = cin.nextBigDecimal();            d.x = cin.nextBigDecimal();            d.y = cin.nextBigDecimal();            point ans = tcircle(a, b, c);            BigDecimal tmp = hypot(d.x.subtract(ans.x), d.y.subtract(ans.y));            if(tmp.compareTo(redius)<=0){                System.out.println("Rejected");            }else                 System.out.println("Accepted");        }    }    static BigDecimal hypot (BigDecimal x,BigDecimal y){        return x.multiply(x).add(y.multiply(y));    }    static point tcircle(point pt1,point pt2,point pt3){        BigDecimal x1=pt1.x,x2=pt2.x,x3=pt3.x;        BigDecimal y1 = pt1.y,y2=pt2.y,y3=pt3.y;        BigDecimal a = x1.subtract(x2);        BigDecimal b = y1.subtract(y2);        BigDecimal c = x1.subtract(x3);        BigDecimal d = y1.subtract(y3);        BigDecimal e = ((x1.multiply(x1).subtract(x2.multiply(x2))).add(y1.multiply(y1).subtract(y2.multiply(y2)))).divide(BigDecimal.valueOf(2.0));        BigDecimal f = ((x1.multiply(x1).subtract(x3.multiply(x3))).add(y1.multiply(y1).subtract(y3.multiply(y3)))).divide(BigDecimal.valueOf(2.0));        BigDecimal det = b.multiply(c).subtract(a.multiply(d));        if(det.abs().doubleValue()<1e-12){            redius = BigDecimal.valueOf(-1);            return new point(BigDecimal.ZERO,BigDecimal.ZERO);        }        BigDecimal x0 = (d.multiply(e).subtract(b.multiply(f))).multiply(BigDecimal.valueOf(-1)).divide(det);        BigDecimal y0 = (a.multiply(f).subtract(c.multiply(e))).multiply(BigDecimal.valueOf(-1)).divide(det);        redius = hypot(x1.subtract(x0), y1.subtract(y0));        return new point(x0, y0);    }}class point{    BigDecimal x,y;    public point(){            }    public point(BigDecimal x,BigDecimal y) {        this.x = x;        this.y = y;    }}


原创粉丝点击