The Mummy Returns

The Mummy Returns

Time Limit: 2 Sec  Memory Limit: 128 MB

Description

      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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值