The Mummy Returns
Time Limit: 2 Sec Memory Limit: 128 MBDescription
The mummy returns! Imhotep has caught O’Connell’s little child to the Oasis of Ahm Shere to resurrect the Scorpion King. To rescue their son, O’Connell and Evelyn follow him, as well as our famous playboy, Jonathan. The Scorpion King gobbles up the power of Imhotep and becomes more powerful. The only way to kill him is to stab him with the Sword of Holy, which is in the hand of our playboy. This was simple because Jonathan was good at playing dart. But things turn bad when Imhotep is between Jonathan and the Scorpion King. If the sword stabs Imhotep before the Scorpion King, Imhotep will get back his power and become unbeatable! The two heroes, O’Connell and Evelyn, are fighting to make the two devil unmoved, and the playboy, Jonathan, is trying to kill the Scorpion King without hurting Imhotep. Will he make it?
To simplify the problem, we assume that the two devils are two untouched circles, the sword is a point outside the circles, and its flying path is a straight ray. Giving the description of the two circles and the point, can you tell if there is a ray from the point which can intersect the circle of the Scorpion King without intersect the circle of Imhotep? Here two items intersect means they share at least one common point.
Input
The input file consists of multiple test cases.
The only one line of each test case consists following parameters: Xs, Ys, Xi, Yi, Ri, Xk, Yk, Rk.
(Xs, Ys) is the location of the Sword of Holy.
(Xi, Yi) is the location of Imhotep, and Ri is its radius.
(Xk, Yk) is the location of the Scorpion King, and Rk is its radius.
Your program should process to the end of the input file.
Output
For each test case, output one line consisting of one English word “Yes” if Jonathon can kill the Scorpion King without hurt Imhotep, or “No” if not.
Sample Input
0 0 0 1 0.5 0 3 0.5 0 0 0 1 0.5 1 0 0.5
Sample Output
No Yes
HINT
The two circles will never intersect or cover each other, and the point is always outside the two circles.
题目大意:平面内给一个点两个圆,从点发射射线是否只与第二圆有交点,而不与第一个圆相交。
wa了半天在于用了模板却没注意到射线反向与第一个圆相交是不算在内的
所以getTangents里加了这个判定
if(dcmp(t1)<0 || dcmp(t2)<0) return 0;
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<vector>
#define PI acos(-1.0)
using namespace std;
const double eps=1e-10;
int dcmp(double x)
{
if(fabs(x)<eps) return 0;
else return x<0?-1:1;
}
struct Point{
double x,y;
Point (double x=0,double y=0):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 - (Vector A, Vector B) { return Vector(A.x - B.x, A.y - B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x / p, A.y / p); }
struct Circle{
Point c;
double r;
Circle(){}
Circle(Point c,double r):c(c),r(r){}
Point point(double a)
{
return Point(c.x+cos(a)*r,c.y+sin(a)*r);
}
};
struct Line
{
Point p;
Vector v;
double ang;
Line() {}
Line(Point p,Vector v):p(p),v(v){ang=atan2(v.y,v.x);}
bool operator < (const Line& L) const {
return ang<L.ang;
}
Point point(double t)
{
return p+v*t;
}
};
double Dot(Vector A, Vector B)
{
return A.x*B.x+A.y*B.y;
}
double Length(Vector A)
{
return sqrt(Dot(A,A));
}
Vector Rotate(Vector A,double rad)
{
return Vector(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));
}
int getLineCircleIntersection(Line L,Circle C,double& t1,double& t2,vector<Point>& sol)
{
double a=L.v.x, b=L.p.x-C.c.x, c=L.v.y, d=L.p.y-C.c.y;
double e=a*a+c*c, f=2*(a*b+c*d),g=b*b+d*d-C.r*C.r;
double delta=f*f-4*e*g;
if(dcmp(delta)<0) return 0;
if(dcmp(delta)==0)
{
t1=t2=-f/(2*e);
sol.push_back(L.point(t1));
return 1;
}
t1=(-f-sqrt(delta))/(2*e);
sol.push_back(L.point(t1));
t2=(-f+sqrt(delta))/(2*e);
sol.push_back(L.point(t2));
if(dcmp(t1)<0 || dcmp(t2)<0) return 0;
return 2;
}
int getTangents(Point p,Circle C,Vector* v)
{
Vector u=C.c-p;
double dist=Length(u);
if(dist<C.r) return 0;
else if(dcmp(dist-C.r)==0)
{
v[0]=Rotate(u,PI/2);
return 1;
}
else
{
double ang=asin(C.r/dist);
v[0]=Rotate(u,-ang);
v[1]=Rotate(u,+ang);
return 2;
}
}
int main()
{
Point p;
Circle cir1,cir2;
while(scanf("%lf%lf",&p.x,&p.y)!=EOF)
{
scanf("%lf%lf%lf%lf%lf%lf",&cir1.c.x,&cir1.c.y,&cir1.r,&cir2.c.x,&cir2.c.y,&cir2.r);;
Vector v2[5];
int va=getTangents(p,cir2,v2);
Line line1(p,v2[0]),line2(p,v2[1]);
double t1,t2;
vector<Point> sol;
int g1=getLineCircleIntersection(line1,cir1,t1,t2,sol),g2=getLineCircleIntersection(line2,cir1,t1,t2,sol);
if(!g1||!g2)
printf("Yes\n");
else printf("No\n");
}
return 0;
}