http://poj.org/problem?id=1375
题目大意:有一盏灯,求每段被圆的投影所覆盖的区间。
——————————————————————
神题,卡精度,尝试用各种方法绕过精度都不行……会了之后直接抄代码吧……
求切线和卡精度秘制写法请参考这个博客:http://blog.csdn.net/acm_cxlove/article/details/7896110、
#include<cstdio> #include<queue> #include<cctype> #include<cstring> #include<vector> #include<cmath> #include<algorithm> using namespace std; typedef double dl; const int N=501; const dl eps=0.000001; struct point{ dl x; dl y; dl r; }p[N],st; struct line{ dl l; dl r; }ans[N]; int n,cnt; bool cmp(line a,line b){ return a.l<b.l; } inline dl dis(point a,point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } inline void tangent(point a,point s){ dl l=dis(s,a); dl m=asin(a.r/l); dl n=asin((s.x-a.x)/l); line k; k.l=s.x-s.y*tan(m+n); k.r=s.x-s.y*tan(n-m); ans[++cnt]=k; return; } int main(){ bool flag=0; while(scanf("%d",&n)!=EOF&&n){ if(flag)putchar(' '); flag=1; cnt=0; scanf("%lf%lf",&st.x,&st.y); for(int i=1;i<=n;i++){ scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].r); tangent(p[i],st); } sort(ans+1,ans+cnt+1,cmp); dl L=ans[1].l,R=ans[1].r; for(int i=2;i<=cnt;i++){ if(ans[i].l>R){ printf("%.2f %.2f ",L,R); L=ans[i].l;R=ans[i].r; }else{ R=max(R,ans[i].r); } } printf("%.2f %.2f ",L,R); } return 0; }