1. 程式人生 > >(圖論)51NOD 1298 圓與三角形

(圖論)51NOD 1298 圓與三角形

給出圓的圓心和半徑,以及三角形的三個頂點,問圓同三角形是否相交。相交輸出"Yes",否則輸出"No"。(三角形的面積大於0)。    

輸入

第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)

輸出

共T行,對於每組輸入資料,相交輸出"Yes",否則輸出"No"。

輸入樣例

2
0 0 10
10 0
15 0
15 5
0 0 10
0 0
5 0
5 5

輸出樣例

Yes
No
解:這道題本身不難,只要確定好分類討論的角度就能ac。
  我的想法就是通過求點到線段的距離來求解。
 1 #include <stdio.h>
 2 #define sq(a) ((a) * (a))
 3 int main()
 4 {
 5     int t;
 6     while (scanf_s("%d", &t) != EOF)
 7     {
 8         while
(t--) 9 { 10 long long cx, cy, cr[2], tx[3], ty[3], dis[3], flag = 0; 11 scanf_s("%lld%lld%lld%lld%lld%lld%lld%lld%lld", &cx, &cy, &cr[0], &tx[0], &ty[0], &tx[1], &ty[1], &tx[2], &ty[2]); 12 cr[1] = sq(cr[0]); 13 for
(int i = 0; i < 3; ++i) 14 { 15 dis[i] = sq(tx[i] - cx) + sq(ty[i] - cy); 16 if (dis[i] > cr[1]) flag += 1; 17 else if (dis[i] == cr[1]) 18 { 19 flag = 1; 20 break; 21 } 22 } 23 if (3 == flag) 24 { 25 flag = 0; 26 for (int i = 0; i < 3; ++i)//判斷點到線段的距離 27 { 28 if (sq(tx[i] - tx[(i + 1) % 3]) + sq(ty[i] - ty[(i + 1) % 3]) + dis[i] > dis[(i + 1) % 3] 29 && sq(tx[i] - tx[(i + 1) % 3]) + sq(ty[i] - ty[(i + 1) % 3]) + dis[(i + 1) % 3] > dis[i])//餘弦定理 30 if (sq((ty[i] - ty[(i + 1) % 3])*cx + (tx[(i + 1) % 3] - tx[i])*cy + tx[i] * ty[(i + 1) % 3] - tx[(i + 1) % 3] * ty[i]) 31 <= (sq(ty[i] - ty[(i + 1) % 3]) + sq(tx[i] - tx[(i + 1) % 3]))*cr[1])//點到直線公式 32 { 33 flag = 1; 34 break; 35 } 36 } 37 38 } 39 switch (flag) 40 { 41 case 0: 42 printf("No\n"); 43 break; 44 case 1:case 2: 45 printf("Yes\n"); 46 break; 47 } 48 } 49 } 50 return 0; 51 }