题目链接:https://cn.vjudge.net/problem/HDU-6097

知识点:  计算几何、圆的反演

题目大意:

  已知一个圆心在原点的圆的半径,再给定 \(P, Q\) 两点坐标( \(PO=QO\),\(P, Q\) 不在圆外),在圆上取一点 \(D\),求 \(PD+QD\) 的最小值。

解题思路:

  首先,\(P, Q\) 两点重合的情况要特判;

  其次,\(P, Q\) 在圆上的情况也要特判(将 \(D\) 点放在 \(P\) 或 \(Q\) 点上即可,答案为 \(|PQ|\) );

  最后一种情况:

  先介绍一下圆的反演这个概念:

  圆的反演就是对于圆\(O\)所在平面的任意一点 \(S\) ,找到一个点 \(S'\) ,使得满足以下条件:

  \(1)\) \(S'\) 在直线 \(OS\) 上;

  \(2)\) \(|OS||OS'| = R^2\),\(R\) 为圆的半径(由这个条件可以利用相似三角形的性质推导出反演的一个性质:对于圆上任意一点 \(P\) ,有 \(\triangle POS \sim \triangle S'OP\));

  圆的反演点还有一个重要的性质:圆内的反演点在圆外,圆外的反演点在圆内,圆上的反演点是它本身。

  具体可以看看这篇文章

  先求出 \(P, Q\) 的反演点 \(P', Q'\),由反演的性质易知 \(\triangle P'OD \sim \triangle DOP\),\(PD = PO*P'D/r\),同理有 \(QD = QO*Q'D/r\),则 \(PD+QD = PO/r(P'D+Q'D)\)。故我们只需求出 \(P'D+Q'D\) 的最小值即可,因为圆内的反演点在圆外,而圆外的情况是比较容易处理的。

  如果 \(P'Q'\) 与圆有交点,则 \(P'D+Q'D\) 的最小值即为 \(|P'Q'|\);否则 \(D\) 取 \(P'Q'\) 的中垂线与圆的交点。

  具体细节请看代码。

AC代码:

 #include <bits/stdc++.h>
using namespace std;
const double eps=1e-;
int dcmp(double x){
if(fabs(x)<eps) return ;
else return x<?-:;
}
struct Point{
double x,y;
Point(double x=,double y=):x(x),y(y){}
};typedef Point Vector;
Vector operator +(Vector A,Vector B){
return Vector(A.x+B.x,A.y+B.y);
}
Vector operator -(Point A,Point B){
return Vector(A.x-B.x,A.y-B.y);
}
Vector operator *(double p,Vector A){
return Vector(A.x*p,A.y*p);
}
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 Dot(Vector A,Vector B){//求向量点积
return A.x*B.x+A.y*B.y;
}
double Length(Vector A){
return sqrt(Dot(A,A));
}
double Cross(Vector A,Vector B){
return A.x*B.y-A.y*B.x;
}
Point O;//坐标原点 Point Inver(Point a,double r){//求反演点
double dis=sqrt(a.x*a.x+a.y*a.y);
double t=r*r/dis/dis;
return Point(t*a.x,t*a.y);
}
double DistanceToLine(Point P,Point A,Point B){//求直线AB到点P的距离
Vector v1=B-A,v2=P-A;
return fabs(Cross(v1,v2))/Length(v1);
}
double cal(Point A,Point B,double r){//求直线AB的中垂线与圆的交点D,并返回|AD|+|BD|
double dis=Dis(A,O);
double ang=acos(Dot(A,B)/(dis*dis))/2.0;//利用cos<v1,v2> = v1*v2/(|v1||v2|)这条性质求两个向量的夹角的一半
return 2.0*sqrt(r*r+dis*dis-*r*dis*cos(ang));
} int main(){
// freopen("in.txt","r",stdin);
int T;
int r1,xq1,yq1,xp1,yp1;
Point P,Q,rP,rQ;
scanf("%d",&T);
while(T--){
scanf("%d",&r1);
scanf("%d%d%d%d",&xp1,&yp1,&xq1,&yq1);
P=Point((double)xp1,(double)yp1),Q=Point((double)xq1,(double)yq1);
double r=(double)r1;
if(xq1==xp1&&yq1==yp1){//特判1
printf("%.7lf\n",2.0*(r-Dis(P,O)));
continue;
}
if(xp1*xp1+yp1*yp1==r1*r1){//特判2
printf("%.7lf\n",Dis(P,Q));
continue;
}
rP=Inver(P,r),rQ=Inver(Q,r);
double d=DistanceToLine(O,rP,rQ); if(dcmp(d-r)>)
printf("%.7lf\n",cal(P,Q,r));
else
printf("%.7lf\n",Dis(P,O)/r*Dis(rP,rQ));
}
return ;
}

HDU6097 Mindis的更多相关文章

  1. 【计算几何】【圆反演】hdu6097 Mindis

    给你一个中心在原点的圆,再给你俩在圆内且到原点距离相等的点P,Q,让你在圆上求一点D,最小化DP+DQ. http://blog.csdn.net/qq_34845082/article/detail ...

  2. hdu6097 Mindis(几何)

    题解: 这里是用解析解的做法, 我们发现如果以P和Q做椭圆,那么当椭圆与圆相切的时候,答案最优 那么方程就是这样的 联立之后,解delta等于0,可以得到 答案就是2a了 注意不一定任何情况都有解,当 ...

  3. hdu 6097 Mindis(数学几何,圆心的反演点)

    Mindis Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  4. hdu6097[二分+解析几何] 2017多校6

    /*hdu6097[二分+解析几何] 2017多校6*/ #include <bits/stdc++.h> using namespace std; ; struct node{ doub ...

  5. 2019 年百度之星·程序设计大赛 - 初赛一 C. HDU 6670 Mindis 离散化+dijkstra

    题目链接 :http://acm.hdu.edu.cn/showproblem.php?pid=6670 Mindis Time Limit: 4000/2000 MS (Java/Others) M ...

  6. 2017ACM暑期多校联合训练 - Team 6 1002 HDU 6097 Mindis (数学)

    题目链接 Problem Description The center coordinate of the circle C is O, the coordinate of O is (0,0) , ...

  7. HDU 6097 Mindis (计算几何)

    题意:给一个圆C和圆心O,P.Q是圆上或圆内到圆心距离相等的两个点,在圆上取一点D,求|PD| + |QD|的最小值 析:首先这个题是可以用三分过的,不过也太,.... 官方题解: 很不幸不总是中垂线 ...

  8. 2017多校第6场 HDU 6097 Mindis 计算几何,圆的反演

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6097 题意:有一个圆心在原点的圆,给定圆的半径,给定P.Q两点坐标(PO=QO,P.Q不在圆外),取圆 ...

  9. 2019 年百度之星·程序设计大赛 - 初赛一 C. Mindis 离散化+dijkstra

    题目传送门 题意:中文题面 思路: 先将所有题目给出的点离散化一下,得到一张n*m的网格,n和m最大都是400,所以我们只需要枚举每个加强的区域,将属于这个区域的边处理一下(所有横着的和竖着的边,暴力 ...

随机推荐

  1. Linux 软链接和硬链接

    系统链接文件 文件有文件名和数据,在Linux上被分成两个部分:用户数据(user data)与元数据(metadata) 用户数据:文件数据块(data block),数据块是记录文件真实内容的地方 ...

  2. SAP WM TO Print Control设置里,Movement Type 的优先级更高

    SAP WM TO Print Control设置里,Movement Type 的优先级更高 存储类型的配置: 从storage type GRM 搬到任何地方,都不需要打印TO单. 移动类型的配置 ...

  3. CSS开发技巧(三):图片点击缩放

    前言  利用CSS实现图片的点击缩放是一个很值得研究的效果.在某些业务需求场景中,我们可能并没有足够的空间展示过大的图片,这就需要限制图片容器的宽度和高度.然而图片限制了宽度,一些图片的细节便又无法看 ...

  4. 集合框架-day10

    day10-集合框架-对象数组的概述与引用 1 集合框架的简单介绍: A:集合的由来 数组长度是固定,当添加的元素超过了数组的长度时需要对数组重新定义,太麻烦,java内部给我们提供了集合类,能存储任 ...

  5. ajax无刷新上传和下载

    关于ajax无刷新上传和下载 这是一个没什么含量但是又用的比较多又不得不说的问题,其实真的不想说,因为没什么好说的. 关于上传 1.使用Flash,ActiveX 上传 ,略... 2.自己写XMLH ...

  6. 历史上的今天mysql数据库包含详情分类以及图片

    历史上的今天mysql数据库包含详情分类以及图片 https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.50111debo71iaJ& ...

  7. Java中常用七个阻塞队列的总结

    Java队列总结 通过前面文章的学习,我们对Java中常用队列做了介绍.本文,咱们来对队列做个总结吧. 首先,我们介绍了现实生活中的实际场景(排队买票等),来告诉我们为什么需要使用队列. 队列是一种先 ...

  8. 5) ModelSerializer(重点) 基表 测试脚本 多表关系建外键 正反查 级联 插拔式连表 序列化反序列化整合 增删查 封装response

    一.前戏要做好 配置:settings.py #注册drf INSTALLED_APPS = [ # ... 'api.apps.ApiConfig', 'rest_framework', ] ​ # ...

  9. zabbix分布式安装全过程

    项目规划 软件 版本 IP zabbix-server 3.4.15 10.1.10.128 zabbix-proxy 3.4.15 10.1.10.129 zabbix-agent 3.4.15 1 ...

  10. python数据统计分析

    1. 常用函数库   scipy包中的stats模块和statsmodels包是python常用的数据分析工具,scipy.stats以前有一个models子模块,后来被移除了.这个模块被重写并成为了 ...