多校6 HDU-6097 Mindis 几何数学

原题链接:
HDU-6097

大意:
院内有两点 P ,Q,在圆上找一点 D ,求 PD+QD 最小。

官方题解:

这里写图片描述

思路:
点关于圆的反演。
关于反演的知识:

中文词条名:反演点
英文词条名:inverse point
一般指二维反演中的点。
二维上反演以一个特定的反演圆为基础:圆心 O 为反演中心,圆半径为常数 r ,把点 P 反演为点 P 就是使得

OP×OP=r2

如点 P 在圆外可这样作:过点 P 作圆的切线(两条),两个切点相连与 OP 连线交点就是点 P .
如点 P 在圆内就把这一过程反过来即可:连结 OP,过点 P 作直线垂直于 OP ,直线与圆的交点处的切线的交点就是点 P .
如点P在圆上,反演后仍是它自身.按上述方法都可用尺规作图完成.
设点M关于圆的反演点是 N ,则该圆上任意一点 P
PMPN=OMON

两个块级公式比较重要。构造过程也要掌握。

做出反演点,把 DP 转化成 DP 来求,所以转化成求 PQ 与圆是否有交点, 若存在则为交点处为 D 具体公式是 k×PQ
上图吧
这里写图片描述
这里写图片描述
这里写图片描述

代码都是数学公式

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mem(s,t) memset(s,t,sizeof(s))
//#define D(v) cout<<#v<<" "<<v<<endl
#define inf 0x3f3f3f3f
//#define LOCAL
inline void read(int &x){
    x=0;char p=getchar();
    while(!(p<='9'&&p>='0'))p=getchar();
    while(p<='9'&&p>='0')x*=10,x+=p-48,p=getchar();
}
double sq(double x){return x*x;}
double dis(double a,double b,double c,double d){return sqrt(sq(a-c)+sq(b-d));}
bool check(double a,double b,double c){
    if(sq(a)+sq(b)<=sq(c))return 1;
    if(sq(b)+sq(c)<=sq(a))return 1;
    if(sq(a)+sq(c)<=sq(b))return 1;
    return 0;
}
int main() {
#ifdef LOCAL
    freopen("1002.in","r",stdin);
    freopen("out.txt","w",stdout);
#endif
    int t;
    read(t);
    while(t--){
        double r,x1,y1,x2,y2;
        scanf("%lf%lf%lf%lf%lf",&r,&x1,&y1,&x2,&y2);
        double x0=(x1+x2)/2;
        double y0=(y1+y2)/2;
        double r0=dis(x1,y1,0,0);
        if(r0==0){
            printf("%lf\n",2*r);
            continue;
        }
        double rr=sq(r)/r0;
        double xp=rr/r0*x1,xq=rr/r0*x2;
        double yp=rr/r0*y1,yq=rr/r0*y2;
        double rt=dis(x0,y0,0,0);
        double xm=r/rt*x0;
        double ym=r/rt*y0;
        double PM=dis(xp,yp,xm,ym);
        if(check(PM,r,rr)){
            printf("%.7lf\n",2*dis(xm,ym,x1,y1)); 
        }else {
            double lambda=sqrt(r0/rr);
            printf("%.7lf\n",lambda*dis(xp,yp,xq,yq));
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值