zoj 2318 Get Out!

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1318

推荐解题报告:http://www.cppblog.com/Yuan/archive/2010/05/02/114163.html

自己对几何题目是一窍不通呀,尤其是精度问题 狂晕,这题也是看了别人的解析

思路,把人所在位置移动到原点,其他点也移动相应位置,然后把人的船当成点,这样的话其他岛屿的半径统一加上船的半径就可以了

然后相交的岛屿连线,看能不能有一个多边形把原点包起来

判别方法,根据点积求角度,根据叉积求正负,然后看有没有负环

更新时dist[i][j]>dist[i][l]+dist[l][j]+eps;  不是很明白为什么要加eps

代码:

#include<iostream>

#include<cstdio>

#include<string>

#include<algorithm>

#include<vector>

#include<string>

#include<cstring>

#include<vector>

#include<queue>

#include<stack>

#include<set>

#include<map>

#include<cmath>



#define LL long long



using namespace std;



const int INF=0x3f3f3f3f;

const double FINF=1e9;

const double eps=1e-6;

const double PI=acos(-1.0);

const int N=305;

struct node

{

    double x,y,r;

}circle[N];

double dist[N][N];

double Fdist(const node& a,const node& b)

{

    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));

}

double crossProduct(const node& a,const node& b)

{

    return a.x*b.y-a.y*b.x;

}

double dotProduct(const node& a,const node& b)

{

    return a.x*b.x+a.y*b.y;

}

int main()

{

    double a=1.0,b=2.5,c=5.0;

    while(c>a+b)

    c=a+b;

    cout<<c<<endl;

    //freopen("data.in","r",stdin);

    int T;

    cin>>T;

    while(T--)

    {

        int n;

        cin>>n;

        for(int i=1;i<=n;++i)

        cin>>circle[i].x>>circle[i].y>>circle[i].r;

        cin>>circle[0].x>>circle[0].y>>circle[0].r;

        for(int i=1;i<=n;++i)

        {

            circle[i].x-=circle[0].x;

            circle[i].y-=circle[0].y;

            circle[i].r+=circle[0].r;

        }

        circle[0].x=0.0;

        circle[0].y=0.0;

        circle[0].r=0.0;

        for(int i=1;i<=n;++i)

        for(int j=i;j<=n;++j)

        {

            if(i==j||circle[i].r+circle[j].r-eps<Fdist(circle[i],circle[j]))

            dist[i][j]=dist[j][i]=INF;

            else

            {

                double C=acos(dotProduct(circle[i],circle[j])/

                              (Fdist(circle[i],circle[0])*Fdist(circle[j],circle[0])));

                bool flag=(crossProduct(circle[i],circle[j])>=0.0)?true:false;

                dist[i][j]=(flag==true)?C:-C;

                dist[j][i]=-dist[i][j];

            }

        }

        for(int l=1;l<=n;++l)

        for(int i=1;i<=n;++i)

        for(int j=1;j<=n;++j)

        if(dist[i][j]>dist[i][l]+dist[l][j]+eps)

        dist[i][j]=dist[i][l]+dist[l][j]+eps;

        bool flag=true;

        for(int i=1;i<=n;++i)

        if(dist[i][i]<-2*PI)

        {flag=false;break;}

        if(flag==true)

        cout<<"YES"<<endl;

        else

        cout<<"NO"<<endl;

        if(T>0)

        cout<<endl;

    }

    return 0;

}

  

你可能感兴趣的:(get)