HDU 6097 Mindis(计算几何)
来源:互联网 发布:鬼魂探测器软件 编辑:程序博客网 时间:2024/06/06 01:41
原题链接
Problem Description
The center coordinate of the circle C is O, the coordinate of O is (0,0) , and the radius is r.
P and Q are two points not outside the circle, and PO = QO.
You need to find a point D on the circle, which makes PD+QD minimum.
Output minimum distance sum.
Input
The first line of the input gives the number of test cases T; T test cases follow.
Each case begins with one line with r : the radius of the circle C.
Next two line each line contains two integers x , y denotes the coordinate of P and Q.
Limits
T≤500000
−100≤x,y≤100
1≤r≤100
Output
Sample Input
4
4
4 0
0 4
4
0 3
3 0
4
0 2
2 0
4
0 1
1 0
Sample Output
5.6568543
5.6568543
5.8945030
6.7359174
题目大意
给一个圆和园内的两个点,保证这两个点与圆心的距离相同,现要在圆上找到一个点使得圆上的点与给出的两个点的距离和最小。
解题思路
引用官方题解。这题有个坑就是给出的两个点有可能重合。其他问题不大。
很不幸不总是中垂线上的点取到最小值,考虑点在圆上的极端情况。
做P点关于圆的反演点P’,OPD与ODP’相似,相似比是|OP| : r。Q点同理。
极小化PD+QD可以转化为极小化P’D+Q’D。
当P’Q’与圆有交点时,答案为两点距离,否则最优值在中垂线上取到。
时间复杂度 O(1)
也有代数做法,结论相同。
优秀的黄金分割三分应该也是可以卡过的。
AC代码
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cctype>#include<algorithm>#include<cmath>#include<vector>#include<string>#include<queue>#include<list>#include<stack>#include<set>#include<map>#define ll long long#define ull unsigned long long#define db double//#define rep(i,n) for(int i = 0;i < n; i++)#define rep(i,a,b) for(int i=(a);i<(b);++i)#define fil(a,b) memset((a),(b),sizeof(a))#define cl(a) fil(a,0)#define pb push_back#define mp make_pair#define exp 2.7182818#define PI 3.141592653589793#define inf 0x3f3f3f3f#define fi first#define se second#define eps 1e-8#define MOD 1000000007ll#define sign(x) ((x)>eps?1:((x)<-eps?(-1):(0)))struct point2{ double x,y; point2(){} point2(double _x,double _y) { x=_x,y=_y; } point2 operator-(const point2 &ne) { return point2(x-ne.x,y-ne.y); } point2 operator+(const point2 &ne) { return point2(x+ne.x,y+ne.y); } point2 operator*(const double t) { return point2(x*t,y*t); }};struct line2{ point2 a,b; line2(){} line2(point2 _a,point2 _b) { a=_a; b=_b; }};double dmult(point2 a,point2 b){ return a.x*b.x+a.y*b.y;}double xmult(point2 a,point2 b){ return a.x*b.y-a.y*b.x; } double xmult(point2 o,point2 a,point2 b) { return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y); } double xmult(double x1,double y1,double x2,double y2) { return x1*y2-x2*y1; }double xmult(line2 x,line2 y){ return xmult(x.b-x.a,y.b-y.a); }double length(point2 v){ return sqrt(v.x*v.x+v.y*v.y);}double dist(point2 a,point2 b){ return length(a-b);}double dist2(point2 a,point2 b){ return dmult(a-b,a-b);}using namespace std;double mysqrt(double x) { return max(0.0, sqrt(x)); }int sgn(double x){ if(fabs(x) < eps) return 0; if(x < 0)return -1; else return 1;}bool equal(double a,double b){ if(abs(a-b)<eps) return true; else return false;}int main() { int t; double r; point2 p,q,pp,qq; cin>>t; while(t--) { scanf("%lf",&r); scanf("%lf%lf%lf%lf",&p.x,&p.y,&q.x,&q.y); if(p.x==p.y&&equal(0,p.x)) { printf("%.8f\n",2*r); } else if(p.x==q.x&&p.y==q.y) { printf("%.8f\n",2*(r-length(p))); } else { double ratio=r/length(p); pp.x=p.x*ratio*ratio; pp.y=p.y*ratio*ratio; qq.x=q.x*ratio*ratio; qq.y=q.y*ratio*ratio; //pp,qq为反演点 double distoo=abs(xmult(pp,qq)/dist(pp,qq)); if(distoo-r>-eps) //中垂线 { if(equal(p.y,q.y)) { point2 p1=point2(0,r); point2 p2=point2(0,-r); printf("%.8f\n",min(dist(p1,p)+dist(p1,q),dist(p2,q)+dist(p2,p))); } else { double k=-(qq.x-pp.x)/(qq.y-pp.y); double b=(qq.x-pp.x)*(pp.x+qq.x)/(qq.y-pp.y)/2+(pp.y+qq.y)/2; point2 p1=point2(-(sqrt((k*k+1)*r*r-b*b)+b*k)/(k*k+1),-(k*sqrt(k*k*r*r+r*r-b*b)-b)/(k*k+1)); point2 p2=point2((sqrt((k*k+1)*r*r-b*b)-b*k)/(k*k+1),-(-k*sqrt(k*k*r*r+r*r-b*b)-b)/(k*k+1)); printf("%.8f\n",min(dist(p1,p)+dist(p1,q),dist(p2,p)+dist(p2,q))); } } else //求交点 { if(equal(p.x,q.x)) { double xx=pp.x; point2 p1=point2(xx,sqrt(r*r-xx*xx)); printf("%.8f\n",dist(p1,p)+dist(p1,q)); } else { double k=(pp.y-qq.y)/(pp.x-qq.x); double b=pp.y-(pp.y-qq.y)*pp.x/(pp.x-qq.x); point2 p1=point2(-(sqrt((k*k+1)*r*r-b*b)+b*k)/(k*k+1),-(k*sqrt(k*k*r*r+r*r-b*b)-b)/(k*k+1)); printf("%.8f\n",dist(p1,p)+dist(p1,q)); } } } } return 0;}
- HDU 6097 Mindis(计算几何)
- HDU 6097 Mindis(计算几何)
- HDU 6097 Mindis【计算几何】
- HDU 6097 Mindis(几何)
- (2017多校6)1002/hdu-6097 Mindis(计算几何)
- HDU 6097 Mindis【计算几何+反演点】
- hdu 6097 Mindis(几何)
- HDU 6097 Mindis【几何】
- HDU 6097 Mindis 几何
- hdu 6097 Mindis(几何反演)
- hud 6097 Mindis(几何)
- 多校6 HDU-6097 Mindis 几何数学
- 2017多校六 1002题 hdu 6097 Mindis 相似三角形 计算几何
- HDU 2017 多校联合训练赛6 1002 6097 Mindis 反演变换 计算几何
- hdu6097—Mindis(计算几何)
- 多校 HDU6097 Mindis (几何)
- hdu 6097 Mindis(多校联赛)
- HDU 6097 Mindis(圆的反演)
- react-redux使用小结
- 51单片机中使用ucos ii的优缺点
- NYOJ 59-小明组织活动的任务(置换)
- 模态框总结
- poj 1330 Nearest Common Ancestors(lca st)
- HDU 6097 Mindis(计算几何)
- 刷题——Stall Reservations POJ
- JavaWeb-ssm框架搭建
- js打开本地exe程序
- power designer远程连接oracle数据库并导出E-R图
- C语言中restrict的作用
- 《Drools7.0.0.Final规则引擎教程》番外实例篇——默认条件的陷阱
- javaSE和JavaEE的区别?
- DAY58JavaScript DOM大纲