HDU6206Apple(Java可以过,但是我有一个大胆的想法)

比赛的时候我有些蠢了。。。
本来想这是个签到题,一看69发,0A。接着就怂了。然后我有个大胆的想法,(接下来说大胆的想法)当时把我激动坏了,(真的蠢)没有这个大胆的想法一看有Java 过了的早就想到用大数A了。结果写了好久才发现人家大数A了,才去写Java。。。
这个题的坑在于数据范围超过了double的精度,所以会有精度丢失,用Java大数就怕了。BigDecimal的精度足够。
Java code:

import java.math.*;
import java.util.Scanner;
public class Main{

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner cin=new Scanner(System.in);
        BigDecimal two=new BigDecimal("2.0");
        BigDecimal x1,y1,x2,y2,x3,y3,x,y,X,Y;
        int kase;
        kase=cin.nextInt();
        for(int i=0;i
        {
            x1=cin.nextBigDecimal();
            y1=cin.nextBigDecimal();
            x2=cin.nextBigDecimal();
            y2=cin.nextBigDecimal();
            x3=cin.nextBigDecimal();
            y3=cin.nextBigDecimal();
            X=cin.nextBigDecimal();
            Y=cin.nextBigDecimal();
            BigDecimal a, b, c, g, e, f,r2;
            e=two.multiply(x2.subtract(x1));
            f=two.multiply(y2.subtract(y1));
            //g = x2*x2 - x1*x1 + y2*y2 - y1*y1;
            g=x2.multiply(x2).subtract(x1.multiply(x1)).add(y2.multiply(y2)).subtract(y1.multiply(y1));
            //a = 2 * (x3 - x2);
            a=two.multiply(x3.subtract(x2));
            //b = 2 * (y3 - y2);
            b=two.multiply(y3.subtract(y2));
            //c = x3*x3 - x2*x2 + y3*y3 - y2*y2;
            c=x3.multiply(x3).subtract(x2.multiply(x2)).add(y3.multiply(y3)).subtract(y2.multiply(y2));
            //X = (g*b - c*f) / (e*b - a*f);
            x=g.multiply(b).subtract(c.multiply(f)).divide(e.multiply(b).subtract(a.multiply(f)));
            //Y = (a*g - c*e) / (a*f - b*e);
            y=a.multiply(g).subtract(c.multiply(e)).divide(a.multiply(f).subtract(b.multiply(e)));
            //R = sqrt((X-x1)*(X-x1)+(Y-y1)*(Y-y1));
            r2=x.subtract(x1).multiply(x.subtract(x1)).add(y.subtract(y1).multiply(y.subtract(y1)));
            BigDecimal dis2;
            dis2=X.subtract(x).multiply(X.subtract(x)).add(Y.subtract(y).multiply(Y.subtract(y)));
            if(dis2.compareTo(r2)==1)
                System.out.println("Accepted");
            else
                System.out.println("Rejected");
        }
    }
}

接下来说说害了了我好久的大胆的想法:
用long long 避免小数运算,这样精度就够了。
然而有点复杂,最后放弃了,如果有空了也许会补上AC代码,现在先把错的贴上

HDU6206Apple(Java可以过,但是我有一个大胆的想法)_第1张图片
思路:
首先判断P是否在AB,BC,AC三条边上;
然后判断P和C是同侧还是异侧。
HDU6206Apple(Java可以过,但是我有一个大胆的想法)_第2张图片
如果是同侧,那么如果∠APB比∠ACB小,那点P一定在圆外,否则在园内。

如果是异侧,∠APB+∠ACB要小于180度;
比较大小用到余弦定理。

#include
#include
#include
#include
#include
#include
#include 
#include
//a&3==a%4
using namespace std;
#define ll long long
#define mem(a) memset(a,0,sizeof(a))
const double eps=1e-8;
const int maxn=310;//须填写
const int inf=0x3f3f3f3f;
const ll mod=1000+7;

struct point
{
    ll x,y;
}p[maxn];

ll dis(point a)
{
    return (a.x)*(a.x)+(a.y)*(a.y);
}

bool eq(point a,point b)
{
    if(a.x==b.x&&a.y==b.y)
        return true;
    else return false;
}

point jian(point a,point b)
{
    point c;
    c.x=a.x-b.x;
    c.y=a.y-b.y;
    return c;
}

ll chacheng(point a,point b)
{
    return (a.x*b.y-b.x*a.y)%mod;
}

ll diancheng(point a,point b)
{
    return a.x*b.x+a.y*b.y;
}

bool judge1(point a,point b)
{
    if(a.x*b.x<0)
        return true;
    else
        return false;
}

bool judge2(point a,point b,point c,point d)
{
    ll dian1=diancheng(a,c);
    ll dian2=diancheng(b,d);
    if(dian1*dian2<0)
    {
        if(dian2<0)
            return true;
        else
            return false;
    }
    if(dian2>0)
    {
        dian1=dian1*dian1/dis(a)/dis(c);
        dian2=dian2*dian2/dis(b)/dis(d);
        if(dian1>dian2)
            return true;
        else return false;
    }
    else{
        dian1=dian1*dian1/dis(a)/dis(c);
        dian2=dian2*dian2/dis(b)/dis(d);
        if(dian1return true;
        else return false;
    }

}

bool judge3(point a,point b,point c,point d)
{
    ll dian1=diancheng(a,c);
    ll dian2=diancheng(b,d);
    if(dian1<0&&dian2<0)
        return false;
    else if(dian1>0&&dian2>0)
        return true;
    else{
        if(dian1>0)
        {
            dian1=dian1*dian1/dis(a)/dis(c);
            dian2=dian2*dian2/dis(b)/dis(d);
            if(dian1>dian2)
                return true;
            else return false;
        }
        else{
            dian1=dian1*dian1/dis(a)/dis(c);
            dian2=dian2*dian2/dis(b)/dis(d);
            if(dian1return true;
            else return false;
        }
    }
}

bool judge(point a,point b,point c,point d)
{
    if(eq(a,d)||eq(b,d)||eq(c,d))
        return false;
    point pp2=jian(a,d);
    point pp0=jian(b,d);
    if(pp2.x*pp0.y-pp2.y*pp0.x==0)
    {
        if(judge1(pp0,pp2))
            return true;
        else
            return false;
    }
    ll x1=chacheng(pp2,pp0);
    point pp3=jian(a,c);
    point pp1=jian(b,c);
    ll x2=chacheng(pp3,pp1);
    if(x1*x2>0)
    {
        if(judge2(pp0,pp1,pp2,pp3))
        {
            return true;
        }
        else
            return false;
    }
    else
    {
        if(judge3(pp0,pp1,pp2,pp3))
        {
            return true;
        }
        else
            return false;
    }
}

int main()
{
    int kase;
    scanf("%d",&kase);
    while(kase--)
    {
        for(int i=0;i<4;i++)
        {
            cin>>p[i].x>>p[i].y;
        }
        if(judge(p[0],p[1],p[2],p[3]))
        {
            printf("Accepted\n");
        }
        else{
            printf("Rejected\n");
        }
    }
}

你可能感兴趣的:(hdu,数学)