雪色光晕(计算几何)

题目:雪色光晕

(自己当错题记录的,题解是我转载的,文末有原文链接,侵权我就删`(*>﹏<*)′)

知识点:计算几何

本题要求一个固定的点到一条折线的最短距离。由于折线可以看成是很多条线段,所以可以规约成点到线段的最短距离。

(虽然这个是板子,但不建议直接去百度,毕竟赛场上没有百度

显然,最终的答案一定为以下两种情况的一种:点到直线的最短距离、或点到线段某个端点的最短距离。

什么时候会遇到第二种情况呢?当且仅当点到直线的最短距离所对应的那个点不在线段上。

所以这道题一个最笨的方法就是:先根据线段求出直线两点式,然后求斜率乘积为-1(这样才能垂直)的直线,求出点斜式(还要特判斜率不存在的情况),这样求出两个直线交点,判断交点在不在线段上。如果在的话直接输出初始点到交点距离,否则输出初始点到线段两个端点的最小那个距离。

如果这道题用这种方法来做,计算量将非常大,题目难度也直接飙上1700+。事实上,本题有更简单的做法:

首先如何判断最终能不能取到点到直线距离呢?很简单,把点 PPP 和线段两个端点 AAA 和 BBB ,这三个点连接成一个三角形,判断该三角形的角 AAA 和角 BBB 是否是钝角即可。判断钝角可以直接用勾股定理:a2+b2<c2a^2+b^2<c^2a2+b2<c2 则角 CCC 为钝角。

然后如何求点到直线的距离呢?也很简单,PPP到直线ABABAB 的距离即三角形 PABPABPAB 中ABABAB边上的高。直接用 2∗SABC/AB2*S_{ABC}/AB2∗SABC​/AB即可。而三角形面积可以直接用海伦公式:S=p∗(p−a)∗(p−b)∗(p−c),p=(a+b+c)/2S=\sqrt{p*(p-a)*(p-b)*(p-c)},p=(a+b+c)/2S=p∗(p−a)∗(p−b)∗(p−c)​,p=(a+b+c)/2。

可以发现,换一个做法,原本计算量巨大的题目将极大的减少做题的负担。在赛场上如果发现某题计算量非常大,不妨洗个脸冷静一下,换一个思路可能会豁然开朗。

*请注意,本题如果直接用网上的long long 存点的板子,可能会导致答案错误。因为在计算过程中会出现超过10^9的情况,这样在计算勾股定理的时候再一个平方就会出现爆long long精度的问题。解决办法要么使用__int128或者高精度,要么直接用double存点。

#include<bits/stdc++.h>
using namespace std;
struct point{
    double x,y;
    point(double x,double y):x(x),y(y){}
};
double dis(point a,point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double ar(point A,point B,point C){ //三点三角形面积
    double a=dis(B,C),b=dis(A,C),c=dis(A,B);
    double p=(a+b+c)/2;
    return sqrt(p*(p-a)*(p-b)*(p-c));
}
int jud(point A,point B,point C){       //判断角ABC是钝角
    double a=dis(B,C),b=dis(A,C),c=dis(A,B);

    return b*b>a*a+c*c;
}
double f(point a,point b,point c){  //c点到ab线段的最小距离
    double d1=dis(a,c),d2=dis(b,c);
    if(jud(c,a,b)||jud(c,b,a))
        return min(d1,d2);
    double s=ar(a,b,c);
    double d3=2*s/dis(a,b);
    return min(min(d1,d2),d3);
}
int main(){
    int n,i,j,k;
    double x,y,x0,y0;
    cin>>n;
    cin>>x0>>y0>>x>>y;
    point purple(x,y);
    point red(x0,y0);
    double res=1e16;
    for(i=0;i<n;i++){
        double xt,yt;
        cin>>xt>>yt;
        point temp(red.x+xt,red.y+yt);
        res=min(res,f(red,temp,purple));
        red=temp;
    }
    printf("%.8f",res);
}

作者:比那名居的桃子
链接:【题解】2022年第四场寒假集训营题解_ACM竞赛_ACM/CSP/ICPC/CCPC/比赛经验/题解/资讯_牛客竞赛OJ_牛客网
来源:牛客网

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值