zoukankan      html  css  js  c++  java
  • [poj] 1375 Interval || 圆的切线&和直线的交点

    原题

    每组数据给出一些圆(障碍物)的圆心和半径,一个点和一条线段,求站在这个点,能开到的线段的部分的左端点和右端点。没有则输出“No View”


    相当于求过该点的圆的两条切线,切线外即为可见的地方。
    借鉴于这个blog:http://blog.csdn.net/acm_cxlove/article/details/7896110
    只要求出两条直线和竖直的夹角,然后通过向量旋转即可得到交点横坐标。

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int n;
    double r,d;
    struct point
    {
        double x,y;
        point() {}
        point(double _x,double _y) : x(_x),y(_y) {}
        point operator - (const point &b) const
    	{
    	    return point(b.x-x,b.y-y);
    	}
        double dis()
    	{
    	    return sqrt(x*x+y*y);
    	}
    }p,q;
    struct edge
    {
        double l,r;
        bool operator < (const edge &b) const
    	{
    	    if (l==b.l) return r<b.r;
    	    return l<b.l;
    	}
    }line[510];
    
    int main()
    {
        while (~scanf("%d",&n) && n)
        {
    	scanf("%lf%lf",&p.x,&p.y);
    	for (int i=0;i<n;i++)
    	{
    	    scanf("%lf%lf%lf",&q.x,&q.y,&r);
    	    d=(p-q).dis();
    	    double a=asin(r/d),b=asin((p.x-q.x)/d);
    	    double ang1=a+b,ang2=b-a;
    	    line[i].l=p.x-p.y*tan(ang1);
    	    line[i].r=p.x-p.y*tan(ang2);
    	}
    	sort(line,line+n);
    	double L=line[0].l,R=line[0].r;
    	for (int i=1;i<n;i++)
    	{
    	    if (line[i].l>R)
    	    {
    		printf("%.2f %.2f
    ",L,R);
    		L=line[i].l;
    		R=line[i].r;
    	    }
    	    else R=max(line[i].r,R);
    	}
    	printf("%.2f %.2f
    
    ",L,R);
        }
        return 0;
    }
    
  • 相关阅读:
    第二类斯特林数学习笔记
    [ZJOI2017]树状数组
    「LibreOJ Round #6」花火
    [Ynoi2016]这是我自己的发明 莫队
    codeforces706E
    扩展CRT
    PKUSC2018游记
    「PKUWC 2018」Minimax
    「SHOI2015」(LOJ2038)超能粒子炮・改
    Codeforces712E
  • 原文地址:https://www.cnblogs.com/mrha/p/8087884.html
Copyright © 2011-2022 走看看