您的位置:首页 > 其它

codeforces 2C Commentator problem (1)-- 几何

2014-04-17 20:43 239 查看
C. Commentator problem

time limit per test
1 second

memory limit per test
64 megabytes

input
standard input

output
standard output

The Olympic Games in Bercouver are in full swing now. Here everyone has their own objectives: sportsmen compete for medals, and sport commentators compete for more convenient positions to give a running commentary. Today the main sport events take place at
three round stadiums, and the commentator's objective is to choose the best point of observation, that is to say the point from where all the three stadiums can be observed. As all the sport competitions are of the same importance, the stadiums should be observed
at the same angle. If the number of points meeting the conditions is more than one, the point with the maximum angle of observation is prefered.

Would you, please, help the famous Berland commentator G. Berniev to find the best point of observation. It should be noted, that the stadiums do not hide each other, the commentator can easily see one stadium through the other.

Input

The input data consists of three lines, each of them describes the position of one stadium. The lines have the format x,  y,  r, where
(x, y) are the coordinates of the stadium's center ( -  103 ≤ x,  y ≤ 103),
and r (1 ≤ r  ≤ 103)
is its radius. All the numbers in the input data are integer, stadiums do not have common points, and their centers are not on the same line.

Output

Print the coordinates of the required point with five digits after the decimal point. If there is no answer meeting the conditions, the program shouldn't print anything. The output data should be left blank.

题目大意是有3个圆,求一点a,使点a对三个圆的视角相等(过a做圆的两条切线,此两切线的夹角即为视角)。若有多点视角相等,则取视角最大的点。

设三个圆的半径分别为r1,r2,r3。设点a(x,y)到三个圆的圆心距离分别为d1,d2,d3。则r1/d1 = r2/d2 = r3/d3即可,设r1/d1 = r2/d2 = r3/d3=r;则有方程:

(x-x1)^2+(y-y1)^2=(r*d1)^2

(x-x2)^2+(y-y2)^2=(r*d2)^2

(x-x3)^2+(y-y3)^2=(r*d3)^3

那么,三个方程,三个未知数,可以求出x,y,r,解的个数可能是0,1,2,当有2个解(r>0)时,若要视角最大,而场馆半径是一定的,显然离得近的大,即r小的解。要人为直接解出方程求出公式是比较难的,但是可以模拟人为计算过程,不过也是比较繁琐,主要是需要细致。=。=

#include<cstdio>
#include<iostream>
#include<cmath>
#include<iomanip>

using namespace std;

int p[3][2];
int r[3];

int main(){
int i,j;
int a[2],b[2],k[2],c[2];
double xr,yr,xc,yc;
double af,bf,cf;
double deta,maxd,mind;
double rs,x,y;

#if defined(DEBUG)||defined(TEST)
freopen("data","r",stdin);
#endif

for(i=0;i<3;i++){
cin>>p[i][0]>>p[i][1]>>r[i];
}

#ifdef DEBUG
for(i=0;i<3;i++){
cout<<p[i][0]<<"\t"<<p[i][1]<<"\t"<<r[i]<<endl;
}
#endif

a[0] = 2*(p[0][0]-p[1][0]);
a[1] = 2*(p[1][0]-p[2][0]);
b[0] = 2*(p[0][1]-p[1][1]);
b[1] = 2*(p[1][1]-p[2][1]);
k[0] = r[1]*r[1] - r[0]*r[0];
k[1] = r[2]*r[2] - r[1]*r[1];
c[0] = p[1][0]*p[1][0] - p[0][0]*p[0][0] + p[1][1]*p[1][1] - p[0][1]*p[0][1];
c[1] = p[2][0]*p[2][0] - p[1][0]*p[1][0] + p[2][1]*p[2][1] - p[1][1]*p[1][1];
c[0] = -c[0];
c[1] = -c[1];

#ifdef DEBUG
cout<<"a\tb\tk\tc\t"<<endl;
for(i=0;i<2;i++){
cout<<a[i]<<"\t"<<b[i]<<"\t"<<k[i]<<"\t"<<c[i]<<endl;
}
#endif

if(a[1]*b[0]-a[0]*b[1] == 0){
#ifdef DEBUG
cout<<"no xr.."<<endl;
#endif
return 0;
}

xr = (double)(k[1]*b[0]-k[0]*b[1])/(a[1]*b[0]-a[0]*b[1]);
xc = (double)(c[1]*b[0]-c[0]*b[1])/(a[1]*b[0]-a[0]*b[1]);
yr = (double)(k[1]*a[0]-k[0]*a[1])/(a[0]*b[1]-a[1]*b[0]);
yc = (double)(c[1]*a[0]-c[0]*a[1])/(a[0]*b[1]-a[1]*b[0]);

#ifdef DEBUG
cout<<"xr:\t"<<xr<<"\txc:\t"<<xc<<"\tyr:\t"<<yr<<"\tyc:\t"<<yc<<endl;
#endif

af = xr*xr+yr*yr;
bf = 2*xc*xr-2*p[1][0]*xr+2*yc*yr-2*p[1][1]*yr-r[1]*r[1];
cf = xc*xc-2*p[1][0]*xc+p[1][0]*p[1][0]+yc*yc-2*p[1][1]*yc+p[1][1]*p[1][1];
deta = bf*bf-4*af*cf;

#ifdef DEBUG
cout<<"af:\t"<<af;
cout<<"\tbf:\t"<<bf;
cout<<"\tcf:\t"<<cf;
cout<<"\tdeta:\t"<<deta<<endl;
#endif

if(af==0){
if( 0==bf && 0!=cf ){
#ifdef DEBUG
cout<<"af=0 , bf=0 , cf!=0"<<endl;
#endif
return 0;
}
if( bf*cf>0 ){
#ifdef DEBUG
cout<<"bf*cf>0"<<endl;
#endif
return 0;
}
x = xc;
y = yc;
}else if(deta<0)
return 0;
else{
deta = sqrt(deta);
maxd = deta-bf;
mind = -bf-deta;
#ifdef DEBUG
cout<<"maxd:\t"<<maxd<<"\tmind:\t"<<mind<<endl;
#endif
if(mind<0)
mind = maxd;
if(maxd<0)
return 0;
else{
rs = mind/2/af;
#ifdef DEBUG
cout<<rs<<endl;
#endif
x = xr*rs+xc;
y = yr*rs+yc;
}
}
cout.setf(ios::fixed);
cout<< setprecision(5) <<x<<" "<<y<<endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: