1. 程式人生 > >[51nod]1298 圓與三角形

[51nod]1298 圓與三角形

alt input 是否 情況 put black namespace bool print

1298 圓與三角形 題目來源: HackerRank 給出圓的圓心和半徑,以及三角形的三個頂點,問圓同三角形是否相交。相交輸出"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 <iostream>
#include <stdio.h>
#include <math.h>
using
namespace std; const double eps = 1e-8; int cmp(double x) { if (fabs(x) < eps) return 0; if (x > 0) return 1; return -1; } struct point { double x, y; point() {} point(double a, double b):x(a),y(b) {} void input() { scanf("%lf%lf", &x, &y); } friend point
operator - (const point &a, const point &b) { return point(a.x-b.x, a.y-b.y); } double norm() { return sqrt(x*x + y*y); } }; struct cicle { point p; double r; void input() { scanf("%lf%lf%lf", &p.x, &p.y, &r); } }; double dot(const point &a, const point &b) { return a.x*b.x + a.y*b.y; } double det(const point &a, const point &b) { return a.x*b.y - a.y*b.x; } double dist(const point &a, const point &b) { return (a-b).norm(); } double dis_point_segment(const point p, const point s, const point t) { if (cmp(dot(p-s,t-s))<0) return (p-s).norm(); if (cmp(dot(p-t,s-t))<0) return (p-t).norm(); return fabs(det(s-p,t-p)/dist(s, t)); } bool cross(cicle o, point a, point b, point c) { double d1, d2, d3; d1 = dist(o.p, a); d2 = dist(o.p, b); d3 = dist(o.p, c); if (d1<o.r && d2<o.r && d3<o.r) return false; if (dis_point_segment(o.p, a, b)>o.r && dis_point_segment(o.p, a, c)>o.r && dis_point_segment(o.p, b, c)>o.r) return false; return true; } int main() { //freopen("1.txt", "r", stdin); int T; scanf("%d", &T); while (T--) { cicle o; o.input(); point a, b, c; a.input(); b.input(); c.input(); if (cross(o, a, b, c)) printf("Yes\n"); else printf("No\n"); } return 0; }

[51nod]1298 圓與三角形