题目描述
在二维平面上给定多个点,判断是否存在三个点共线
基本思想
实现思路
在给定的点中,任意取出三个点 p1,p2,p3 ,一共有 C3n 中情况,只要存在一组三点共线,即可确定存在三个点共线,反之,不存在三点共线。
判断三点共线
根据直线两点式:
y−y1x−x1=y2−y1x2−x1
,只要
p1(x1,y1),p2(x2,y2),p3(x3,y3)
满足下式时,便可判定三点共线:
(y3−y1)(x2−x1)−(y2−y1)(x3−x1)=0
但由于在计算机中小数会有一定的误差,尽量不要用“==”进行比较,应该取一定的误差,例如
|(y3−y1)(x2−x1)−(y2−y1)(x3−x1)|<=10−6
代码实现
// 判断三点共线函数的实现
// 共线返回1
// 不共线返回0
int on_a_line(point a, point b, point c)
{
float tempy1 = (a.y - b.y) ;
float tempx1 = (a.x - b.x);
float tempy2 = (c.y - a.y) ;
float tempx2 = (c.x - a.x);
float xp = tempy1 * tempx2;
float yp = tempy2 * tempx1;
if(fabs(xp - yp) <= 1e-6)
return 1;
else
return 0;
}
题目代码
#include<stdio.h>
#include<math.h>
// 定义坐标点
typedef struct point
{
float x;
float y;
}point;
// 三点共线判断函数
// 共线返回1
// 不共线返回0
int on_a_line(point a, point b, point c);
int main()
{
// 定义测试次数
int case_num = 0;
// 定义点数
int point_num = 0;
// 共线标志,1共线,0不共线
int flag = 0;
int i,j,k,l;
// 输入测试次数
scanf("%d",&case_num);
for(i = 0; i < case_num; i++)
{
// 输入坐标数
scanf("%d",&point_num);
// 声明坐标数组
point points[point_num];
// 输入坐标
for(j = 0; j < point_num; j++)
{
// 输入横坐标x
scanf("%f",&points[j].x);
// 输入纵坐标y
scanf("%f",&points[j].y);
}
// 判断是否存在三点共线
if(point_num >= 3)
{
for(j = 0 ;j < point_num && flag == 0; j++)
{
for(k = j + 1; k < point_num && flag == 0; k++)
{
for(l = k + 1; l < point_num && flag == 0; l++)
{
if(on_a_line(points[j],points[k], points[l]))
flag = 1;
}
}
}
// 打印信息
if(flag == 1)
{
printf("Yes\n");
flag = 0;
}
else
printf("No\n");
}
}
}
// 判断三点共线函数的实现
int on_a_line(point a, point b, point c)
{
float tempy1 = (a.y - b.y) ;
float tempx1 = (a.x - b.x);
float tempy2 = (c.y - a.y) ;
float tempx2 = (c.x - a.x);
float xp = tempy1 * tempx2;
float yp = tempy2 * tempx1;
if(fabs(xp - yp) <= 1e-6)
return 1;
else
return 0;
}