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