HDOJ-WARMUP2 部分题解(不断更新)

1001:水题

1005:计算几何

这是本人第一次写计算几何题,我还是觉得模板要用自己写的,否则真是各种不舒服。。

首先考虑三点共线的情况,若第4个点在这个线段上,则为Danger,否则safe

三点不共线的时候,果断想外接圆,但byijie跟我说不对,因为钝角三角形时,面积最小的圆应该是以长边为直径的圆,这样的话,枚举四个圆即可,一个外接圆,三个以三条边为直径的圆。比赛的时候当然没写完,后来写了写,有些细节处理又请教了byijie...1A。。。附代码:

#include <iostream>
#include <cstdio>
#include <cmath>
 
#define eps 1e-7
#define zero(x) (((x)>0?(x):-(x))<eps)
using namespace std;
 
struct point
{
    double x;
    double y;
    point(){}
    point(double xx,double yy)
    {
        x=xx;y=yy;
    }
};

struct Xl
{
    double x;
    double y;
    Xl(point p1,point p2)
    {
        x=p1.x-p2.x;
        y=p1.y-p2.y;
    }
};

point A,B,C,D;
double xmax,xmin;
            
double dist(point p,point q)
{
    return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y));
}

double crosspoint(point &O,point P,point Q,Xl l1,Xl l2)
{
    double fzy=(P.x-Q.x)*(l1.x*l2.x)+P.y*l1.y*l2.x-Q.y*l2.y*l1.x;
    double fmy=l1.y*l2.x-l2.y*l1.x;
    O.y=fzy/fmy;
    O.x=(P.x*l1.x+P.y*l1.y-O.y*l1.y)/l1.x;
    return dist(O,A);
}

double cha(Xl s1,Xl s2)
{
    return s1.x*s2.y-s1.y*s2.x;
}

int pd()
{
    Xl s1(A,B);
    Xl s2(B,C);
    if (zero(cha(s1,s2)))
    {
        Xl s3(A,D);
        if (zero(cha(s1,s3)))
        {
            if (xmin<D.x-eps&xmax>D.x+eps) return 1;
            else return 0;
        }
        else return 0;
    }
    else
    {
        point E((A.x+B.x)/2,(A.y+B.y)/2);
        point F((B.x+C.x)/2,(B.y+C.y)/2);
        point G((A.x+C.x)/2,(A.y+C.y)/2);
        point O;
        double rmin=crosspoint(O,E,F,s1,s2);
        double dr=dist(O,D);
        if (dist(E,C)<dist(E,A)-eps) 
        {
            if (dist(E,A)<rmin-eps) 
            {
                rmin=dist(E,A);
                dr=dist(E,D);
            }
        }
     
        if (dist(F,A)<dist(F,B)-eps) 
        {
            if (dist(F,B)<rmin-eps) 
            {
                rmin=dist(F,B);
                dr=dist(F,D);
            }
        }
        if (dist(G,B)<dist(G,A)-eps) 
        {
            if (dist(G,A)<rmin-eps) 
            {
                rmin=dist(G,A);
                dr=dist(G,D);
            }
        }
        if (dr>rmin+eps) return 0; 
        else return 1;
    }
}                     

int main()
{
    int T,i,cas;
    cin>>T;
    for (cas=1;cas<=T;cas++)
    {
        cin>>A.x>>A.y;
        xmax=A.x;xmin=A.x;
        cin>>B.x>>B.y;
        if (B.x>xmax) xmax=B.x;
        if (B.x<xmin) xmin=B.x;
        cin>>C.x>>C.y;
        if (C.x>xmax) xmax=C.x;
        if (C.x<xmin) xmin=C.x;
        cin>>D.x>>D.y;
        int stat=pd();
        if (stat) printf("Case #%d: Danger\n",cas);
        else printf("Case #%d: Safe\n",cas); 
        
    }
    return 0;
}


1007:刚开始想多了,竟然用了数位DP,后来发现过的人很多,觉得不对劲,感觉有简单方法,果真如此。因为每连续10个数有且仅有1个符合题目要求的数,这下OK,注意细节,WA了2次吧。。。。晕。。

1012:水题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值