若平面有N个点,求共线的最大点数

话说,有N个点,求共线最大点数,我们可以这么求,点两两构成直线,假设点p1与p2构成直线和p2与p3构成直线一模一样,那么就可以判断p1,p2,p3共线了;再举个例子,假设N个点中,共线的最多点数为m个,那么这m个点组成的直线一定是相同的,所以如果我们求出来了这m个点构成的直线数,那么就可以反求得点数m。基于此,我们定义直线类型,直线类型应该有斜率k,x轴截距,y轴截距,直线数四个参数构成。

叽里咕噜说了一大堆,

#include <stdio.h>
#include<math.h>
///点结构体
typedef struct
{
    double x;
    double y;
} Point;
///直线结构体,每一个直线由三个参数决定,分别是斜率、x轴截距、y轴截距,必须是三个参数
typedef struct
{
    double x_axis;
    double y_axis;
    double k;
    int count;
} Line;
int m=0;
void fun(Line line[],Point point[],int n)
{
    int i,j,t;
    double k,b,x_axis,y_axis;//分别表示直线的斜率,截距,x轴截距,y轴截距
    for(i=0; i<n-1; i++)
    {
        for(j=i+1; j<n; j++)
        {
            ///三个条件语句分别处理垂直于x轴直线,垂直于y轴直线,普通直线
            if(fabs(point[i].x-point[j].x)<1e-5)
            {
                k=1e5;
                x_axis=point[i].x;
                y_axis=1e5;
            }
            else
            {
                if(fabs(point[i].y-point[j].y)<1e-5)
                {
                    k=0;
                    x_axis=1e5;
                    y_axis=point[i].y;
                }
                else
                {
                    k=(point[i].y-point[j].y)/(point[i].x-point[j].x);

                    b=-1.0*k*point[i].x+point[i].y;
                    x_axis=-1*b/k;
                    y_axis=b;
                }
            }


            for(t=0; t<m; t++)//在已产生的直线中找找看该直线是否已存在
            {
                if((fabs(line[t].x_axis-x_axis)<1e-5)&&(fabs(line[t].y_axis-y_axis)<1e-5)&&(fabs(line[t].k-k)<1e-5))
                {
                    line[t].count++;
                    break;
                }
            }
            if(t==m)//说明是新直线
            {
                line[m].x_axis=x_axis;
                line[m].y_axis=y_axis;
                line[m].k=k;
                line[m].count=1;
                m++;
            }
        }
    }
}


int main()
{
    Line line[100];
    Point point[100];
    int n;

    ///从文件中读入点坐标
    FILE *fp=fopen("data.txt","r+");
    fscanf(fp,"%d",&n);
    int i;
    for(i=0; i<n; i++)
    {
        fscanf(fp,"%lf %lf",&point[i].x,&point[i].y);
        printf("%lf %lf\n",point[i].x,point[i].y);
    }
    fun(line,point,n);
    printf("\n---------------------------结果------------------------------:\n\n");
    int j=0;//寻找点数的参数
    int max=0;
    for(i=0; i<m; i++)
    {
        for(j=1; (j*(j-1)/2!=line[i].count)&&(j<line[i].count); j++);///根据直线数点数j与边数目满足,边数=j*(j-1)/2
        printf("在以斜率为%lf,x轴截距为%lf,y轴截距为%lf的直线上点数有:%d个 \n\n",line[i].k,line[i].x_axis,line[i].y_axis,j);
        if(max<=j)
        {
            max=j;
        }
        printf("所以共线最多的点数为%d个\n",max);
    }
}

文件中坐标点数据(第一个数为点个数):
7
0 0
1 1
2 2
3 3
1 2
3 2
3 0

第一次写东西,不容易呐!

猜你喜欢

转载自blog.csdn.net/weixin_42034217/article/details/84502120