题目链接:
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1298
给出圆的圆心和半径,以及三角形的三个顶点,问圆同三角形是否相交。相交输出"Yes",否则输出"No"。(三角形的面积大于0)。
Input
第1行:一个数T,表示输入的测试数量(1 <= T <= 10000),之后每4行用来描述一组测试数据。 4-1:三个数,前两个数为圆心的坐标xc, yc,第3个数为圆的半径R。(-3000 <= xc, yc <= 3000, 1 <= R <= 3000) 4-2:2个数,三角形第1个点的坐标。 4-3:2个数,三角形第2个点的坐标。 4-4:2个数,三角形第3个点的坐标。(-3000 <= xi, yi <= 3000)
Output
共T行,对于每组输入数据,相交输出"Yes",否则输出"No"。
Input示例
2 0 0 10 10 0 15 0 15 5 0 0 10 0 0 5 0 5 5
Output示例
Yes No
题解:
几何模版题。
代码:
#include <math.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #define eps 1e-8 struct point { double x,y; }; typedef struct point point; point O,A,B,C; double r; double xmult(point p1,point p2,point p0) { return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); } double distance(point p1,point p2) { return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); } double disptoline(point p,point l1,point l2) { return fabs(xmult(p,l1,l2))/distance(l1,l2); } point intersection(point u1,point u2,point v1,point v2) { point ret=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)); ret.x+=(u2.x-u1.x)*t; ret.y+=(u2.y-u1.y)*t; return ret; } int intersect_seg_circle(point c,double r, point l1,point l2) { double t1=distance(c,l1)-r,t2=distance(c,l2)-r; point t=c; if (t1<eps||t2<eps) return t1>-eps||t2>-eps; t.x+=l1.y-l2.y; t.y+=l2.x-l1.x; return xmult(l1,c,t)*xmult(l2,c,t)<eps&&disptoline(c,l1,l2)-r<eps; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%lf%lf%lf",&O.x,&O.y,&r); scanf("%lf%lf",&A.x,&A.y); scanf("%lf%lf",&B.x,&B.y); scanf("%lf%lf",&C.x,&C.y); int flag1=intersect_seg_circle(O,r,A,B); int flag2=intersect_seg_circle(O,r,A,C); int flag3=intersect_seg_circle(O,r,B,C); if(flag1||flag2||flag3) printf("Yes "); else printf("No "); } }