HDU6097 Mindis
题目链接: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的更多相关文章
- 【计算几何】【圆反演】hdu6097 Mindis
给你一个中心在原点的圆,再给你俩在圆内且到原点距离相等的点P,Q,让你在圆上求一点D,最小化DP+DQ. http://blog.csdn.net/qq_34845082/article/detail ...
- hdu6097 Mindis(几何)
题解: 这里是用解析解的做法, 我们发现如果以P和Q做椭圆,那么当椭圆与圆相切的时候,答案最优 那么方程就是这样的 联立之后,解delta等于0,可以得到 答案就是2a了 注意不一定任何情况都有解,当 ...
- hdu 6097 Mindis(数学几何,圆心的反演点)
Mindis Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ...
- hdu6097[二分+解析几何] 2017多校6
/*hdu6097[二分+解析几何] 2017多校6*/ #include <bits/stdc++.h> using namespace std; ; struct node{ doub ...
- 2019 年百度之星·程序设计大赛 - 初赛一 C. HDU 6670 Mindis 离散化+dijkstra
题目链接 :http://acm.hdu.edu.cn/showproblem.php?pid=6670 Mindis Time Limit: 4000/2000 MS (Java/Others) M ...
- 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) , ...
- HDU 6097 Mindis (计算几何)
题意:给一个圆C和圆心O,P.Q是圆上或圆内到圆心距离相等的两个点,在圆上取一点D,求|PD| + |QD|的最小值 析:首先这个题是可以用三分过的,不过也太,.... 官方题解: 很不幸不总是中垂线 ...
- 2017多校第6场 HDU 6097 Mindis 计算几何,圆的反演
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6097 题意:有一个圆心在原点的圆,给定圆的半径,给定P.Q两点坐标(PO=QO,P.Q不在圆外),取圆 ...
- 2019 年百度之星·程序设计大赛 - 初赛一 C. Mindis 离散化+dijkstra
题目传送门 题意:中文题面 思路: 先将所有题目给出的点离散化一下,得到一张n*m的网格,n和m最大都是400,所以我们只需要枚举每个加强的区域,将属于这个区域的边处理一下(所有横着的和竖着的边,暴力 ...
随机推荐
- Linux系统介绍与环境搭建准备
1 什么是操作系统? 操作系统,Operating System,简称OS,是计算机系统中必不可少的基础软件,它是应用程序运行以及用户操作必备的基础环境支撑,是计算机系统的核心. 操作系统的作用是 ...
- Shiro(二):Spring-boot如何集成Shiro(上)
这篇文章主要介绍了spring-boot是如何集成shiro的authentication流程的. 从shiro-spring-boot-web-starter说起 shiro-spring-boot ...
- nginx平滑升级、在线添加模块(tengine 动态加载模块)
http://www.orzace.com/how-to-upgrade-nginx/ 下面是nginx替换成tengine再加上lua 模块,(tengine-2.0.1版本暂时无法动态加载lua模 ...
- 从零搭建Prometheus监控报警系统
什么是Prometheus? Prometheus是由SoundCloud开发的开源监控报警系统和时序列数据库(TSDB).Prometheus使用Go语言开发,是Google BorgMon监控系统 ...
- Springboot-WebFlux实现http重定向到https
1 简介 Spring WebFlux是一个新兴的技术,Spring团队把宝都压在响应式Reactive上了,于是推出了全新的Web实现.本文不讨论响应式编程,而是通过实例讲解Springboot W ...
- 蓝色展开收缩悬浮QQ客服代码
放在我的博客首页上的的预览图: 在文章区的预览图如下: 代码如下: <div class="scrollsidebar" id="scrollsidebar&quo ...
- MySQL命令1
开始学习MySQL. // 创建数据库 CREATE DATABASE db_name; // 删除数据库 DROP DATABASE db_name; // 显示数据库 SHOW DATABASES ...
- Java笔记(day20-22)
IO流: 输入流.输出流 字节流.字符流:为了处理文字数据方便而出现的对象. (其实这些对象的内部使用的还是字节流(因为文字最终也是字节数据,只不过,通过字节流读取了相对应的字节数,没有对这些字节直接 ...
- spring学习笔记(四)我对spring中bean生命周期的理解
我相信大部分同学对spring中bean的生命周期都不陌生,但是如果要详细的说出每一个步骤,可能能说出来的也不多,我之前也是这样,前几天调了一下spring的源码,看了一点书,突然一下明朗了,理解了s ...
- apache反向代理和负载均衡
正向代理:正如我们用的游戏加速代理,大多的个人PC把请求发给正向代理服务器,代理服务器通常配置高端的带宽,替我们请求相应的服务 负载均衡中的反向代理:通常意义上,是一个请求转发的代理.类似一个收发室的 ...