FJNU 1151 Fat Brother And Geometry(胖哥与几何)

FJNU 1151 Fat Brother And Geometry(胖哥与几何)

Time Limit: 1000MS   Memory Limit: 257792K

【Description】

【题目描述】

Fat brother enrolled in computer graphics, recently teacher arranged a job: given two straight lines and a circle, judge if the round is between straight two lines. If it is, fat brother need to submit a “Yes” to the teacher. If not, fat brother need to submit “No” to the teacher.

Note:

Straight line will be expressed through two point in it

Circle will be expressed through a center point and a radius

胖哥选修了计算机图形学,最近老师给他布置了个任务: 给定两条直线与一个圆,判断这个圆是否在两条直线中。如果是,提交“Yes”给老师。否则,胖哥需要提交“No”给老师。

注意:

直线以两点表示。

圆以圆心和半径表示。

【Input】

【输入】

There are multiple test cases. The first line of input contains an integer T (T <= 20) indicating the number of test cases. For each test case:

The first line contains four number Ax1, Ay1, Ax2, Ay2 denoting there are two point (Ax1, Ay1), (Ax2, Ay2) on the line A

The second line contains four number Bx1, By1, Bx2, By2 denoting there are two point (Bx1, By1), (Bx2, By2) on the line B

The third line contains three number Ox, Oy, r denoting the center of the circle O is (Ox, Oy) and the radius of the circle O is r

( -10^9 <= x, y, r <= 10 ^ 9)

多组测试用例。

第一行是一个整数T(T <= 20)表示测试用例的数量。对于每个测试用例:

第一行有四个数Ax1, Ay1, Ax2, Ay2表示直线A上的两点(Ax1, Ay1), (Ax2, Ay2)。

第二行有四个数Bx1, By1, Bx2, By2表示直线A上的两点(Bx1, By1), (Bx2, By2)。

第行有三个数Ox, Oy, r表示圆心O的坐标(Ox, Oy)和圆O的半径为r。

( -10^9 <= x, y, r <= 10 ^ 9)

【Output】

【输出】

For each test case, output “Yes” or “No”

对于测试用例,输出“Yes”或“No”。

【Sample Input - 输入样例】

【Sample Output - 输出样例】

2

-5.98 5.98 -8.52 2.01

-2.01 4.97 -6.03 -1.06

-6.96 3.94 1.03

-19.98 11.93 19.95 -2.01

16.01 11.93 -17.97 -12.12

12.04 3.92 2.09

No

Yes

【Hint - 提示】

测试用例一

The first sample test case:

测试用例二

The second sample test case:

 

【题解】

大意是判断圆和直线的关系,不过输入数据是double类型。

由于浮点数的精度,最容易发生问题的地方是在两个数比较是否相等的时候,此时应该算上最低的精度,不过题目也没说精度是多少……按之前看过的类似题目就去10e-8好了。

(一开始条件反射在考虑如何用ax+by+c>0直接判断……想了想发觉没什么卵用)

按直线的位置划分情况:

①两条直线相交:圆心到直线的距离是否大于半径。

②两条直线平行:两条平行线的距离是否大于直径。

接着就是两点式化一般式。 

 

得:(y1 - y2)x + (x2 - x1)y + x1y2-x2y1 = 0

因此:a = y1 - y2,b = x2 - x1,c = x1y2-x2y1

点到直线的距离:

平行线间的距离:

不过两条直线的a,b不定各自相等,转化一下就好了。

之后就没啥好说的了。

【代码 C++】

 1 #include<cstdio>
 2 #include <cmath>
 3 #define Zero 10e-8
 4 int main(){
 5     int t, n;
 6     double x1, y1, x2, y2, a1, b1, c1, a2, b2, c2, r, L1, L2;
 7     while (~scanf("%d", &t)){
 8         while (t--){
 9             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
10             a1 = y1 - y2; b1 = x2 - x1; c1 = x1*y2 - x2*y1;
11             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
12             a2 = y1 - y2; b2 = x2 - x1; c2 = x1*y2 - x2*y1;
13             scanf("%lf%lf%lf", &x1, &y1, &r);
14             L1 = fabs(a1*x1 + b1*y1 + c1) / sqrt(a1*a1 + b1*b1);
15             L2 = fabs(a2*x1 + b2*y1 + c2) / sqrt(a2*a2 + b2*b2);
16             if (L1 < r) puts("No");
17             else if (L2 < r) puts("No");
18             else if (fabs(a1*b2 - a2*b1) > Zero) puts("Yes");
19             else if (fabs(fabs(c1 - c2 / (a2 + b2)*(a1 + b1)) / sqrt(a1*a1 + b1*b1) - L1 - L2) > Zero) puts("No");
20             else puts("Yes");
21         }
22     }
23     return 0;
24 }
原文地址:https://www.cnblogs.com/Simon-X/p/5404187.html