zoj 1309 || poj 1375 Intervals

来源:互联网 发布:dialog数据库 专利 编辑:程序博客网 时间:2024/05/01 09:21

求圆外一点和这些圆的投影。

直接求点和圆的切线与地面的交点,然后按x坐标从小到大排序。然后验证这些点和P的连线是否穿过某个圆,如果穿过,必然不合题意。

中间卡了下精度,如果判断是否穿过某个圆的时候不用eps,我样例都过不去 = =。。。

当然,求和地面的交点可以用解析几何的知识。。。我懒得推。。

#include <map>#include <set>#include <queue>#include <stack>#include <math.h>#include <time.h>#include <stdio.h>#include <stdlib.h>#include <iostream>#include <limits.h>#include <string.h>#include <string>#include <algorithm>#define MID(x,y) ( ( x + y ) >> 1 )#define L(x) ( x << 1 )#define R(x) ( x << 1 | 1 )#define BUG puts("here!!!")#define STOP system("pause")using namespace std;const int MAX = 510;struct point {double x,y;void get(){scanf("%lf%lf",&x,&y);}};struct circle{point c;double r;};point p;circle c[MAX];point ins[MAX*2];point l1,l2;const double eps = 1e-6;bool dy(double x,double y){return x > y + eps;}// x > y bool xy(double x,double y){return x < y - eps;}// x < y bool dyd(double x,double y){ return x > y - eps;}// x >= y bool xyd(double x,double y){return x < y + eps;} // x <= y bool dd(double x,double y) {return fabs( x - y ) < eps;}  // x == ydouble disp2p(point a,point b) //  a b 两点之间的距离 {return sqrt( ( a.x - b.x ) * ( a.x - b.x ) + ( a.y - b.y ) * ( a.y - b.y ) );}// 叉积 (三点)double crossProduct(point a,point b,point c)//向量 ac 在 ab 的方向 顺时针是正 {return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y);}point Rotate(double ang, point a, point b){    b.x -= a.x; b.y -= a.y;    point c;    c.x = b.x * cos(ang) - b.y * sin(ang) + a.x;    c.y = b.x * sin(ang) + b.y * cos(ang) + a.y;    return c;}point l2l_inst_p(point u1,point u2,point v1,point v2){point ans = u1;double t = ((u1.x - v1.x)*(v1.y - v2.y) - (u1.y - v1.y)*(v1.x - v2.x))/((u1.x - u2.x)*(v1.y - v2.y) - (u1.y - u2.y)*(v1.x - v2.x));ans.x += (u2.x - u1.x)*t;ans.y += (u2.y - u1.y)*t;return ans;}void get_point(point p,point c,double r,point &a,point &b){double l = disp2p(c,p);double ang = asin(r/l);a = Rotate(ang, p, c);b = Rotate(-ang, p, c);a = l2l_inst_p(l1, l2, p, a);b = l2l_inst_p(l1, l2, p, b);}bool cmp(point a,point b){return a.x < b.x;}double disp2l(point a,point l1,point l2){return fabs( crossProduct(a,l1,l2) )/disp2p(l1,l2);}bool solve(point ins, int n){for(int k=0; k<n; k++){double len = disp2l(c[k].c, p, ins);if( xy(len,c[k].r) )return false;}return true;}int main(){int n;l1.x = l1.y = 0;l2.x = 10; l2.y = 0;while( ~scanf("%d", &n) && n ){p.get();int cnt = 0;for(int i=0; i<n; i++){c[i].c.get();scanf("%lf", &c[i].r);get_point(p, c[i].c, c[i].r, ins[cnt], ins[cnt+1]);cnt += 2;}sort(ins, ins+cnt, cmp);int k = 0;for(int i=0; i<cnt; i++){if( solve(ins[i], n) ){k++;printf("%.2lf", ins[i].x);if( k % 2 == 0 )printf("\n");elseprintf(" ");}}printf("\n");}return 0;}