1. 程式人生 > >6097 Mindis(反演變換)

6097 Mindis(反演變換)

題目大意:

給你一個圓和圓內到圓心距離相等的兩點 P Q ,讓你在圓上找到一個點 K ,使得這 PK + QK 最小。

分析:

學到一個幾何方面的知識,這麼好用的東西之前我居然沒聽說過,叫做反演。就是在OP的延長線上,取A,使得 OAOP=r2 。從而構造出相似三角形。

未AC程式碼:

#include<bits/stdc++.h>

using namespace std;

double r,px,py,qx,qy,ax,ay,bx,by;
int test;

int main()
{
    scanf("%d",&test);
    while
(test--) { scanf("%lf%lf%lf%lf%lf",&r,&px,&py,&qx,&qy); double op,oq,pq; op=sqrt(px*px+py*py); oq=op; pq=sqrt((px-qx)*(px-qx)+(py-qy)*(py-qy)); if(op+oq-pq<1e-9) { double ans=2.0*sqrt(op*op+r*r); printf("%.
7f\n",ans); continue; } double oa=r*r/op; double c=(op*op+oq*oq-pq*pq)/(2.0*op*oq); double cc=sqrt((c+1)/2.0); //cout<<cc<<endl; /*if(cc<=1e-6) { double ans=oa/r/pq; //cout<<1; printf("%lf
\n",ans); continue; }*/ double dis=oa*cc; if(dis>
r) { double x=sqrt(op*op+r*r-cc*2.0*op*r); double ans=2*x; printf("%.7f\n",ans); //cout<<"dsa"; } else { double ans=pq*r/op; printf("%.7f\n",ans); }- } }

樣例已過,精度或邊界問題。