题目描述
Given points on a 2D plane, judge whether there're three points that locate on the same line.
输入格式
The number of test cases T(1≤T≤10) appears in the first line of input.
Each test case begins with the number of points N(1≤N≤100) . The following N lines describe the coordinates (xi,yi) of each point, in accuracy of at most 3 decimals. Coordinates are ranged in [−104,104]
应该说这是一道比较简单的题目,不过也不能小看,因为有一个需要特别注意的地方,稍后会说到。
解题思路很容易想到:利用穷举来对所有点对都进行判断,若有共线的,则退出循环输出结果。关键在于:如何判断是否共线?其实也很容易想到,那就是利用斜率
y3−y2x3−x2
=
y2−y1x2−x1
然而在进行编程的时候有一个问题:浮点数的精度问题。计算机中进行浮点数的除法运算时很容易丢失精度,造成结果误差。那么要怎么办呢?其实,只要把除法换成乘法,这个问题就完美解决了:
y3−y2x3−x2
=
y3−y1x3−x1
—>
x2y3−x2y2−x1y3+x1y2−x3y2+x2y2+x3y1−x2y1
这样一来,精度的问题就得到了解决。
代码如下:
#include<cstdio>
#include<cmath>
using namespace std;
int main(void)
{
int numt;
scanf("%d",&numt);
for(int i=1; i<=numt; i++)
{
bool isinline=false;
int nop;
scanf("%d",&nop);
float x[nop+1],y[nop+1];
for(int j=1; j<=nop; j++)
scanf("%f %f",&x[j],&y[j]);
for(int k=1; k<=nop&&isinline==false; k++)
for(int l=k+1; l<=nop&&isinline==false; l++)
for(int m=l+1; m<=nop&&isinline==false; m++)
{
if(abs(x[m]*y[l]-x[m]*y[k]-x[l]*y[l]+x[l]*y[k]-x[l]*y[m]+x[k]*y[m]+x[l]*y[l]-x[k]*y[l])<=1e-6)isinline=true;
}
printf((isinline==true)?"Yes\n":"No\n");
}
}