计算平面上连成线的点最大个数

8 篇文章 0 订阅

Lining Up

My Tags1   (Edit)
  Source : ACM ICPC East Central North America 1994
  Time limit : 3 sec   Memory limit : 32 M

Submitted : 1280, Accepted : 362

"How am I ever going to solve this problem?" said the pilot. 

Indeed, the pilot was not facing an easy task. She had to drop packages at specific points scattered in a dangerous area. Furthermore, the pilot could only y over the area once in a straight line, and she had to y over as many points as possible. All points were given by means of integer coordinates in a two-dimensional space. The pilot wanted to know the largest number of points from the given set that all lie on one line. Can you write a program that calculates this number? Your program has to be efficient!

Input:

There are multiple test cases!
The input consists of N pairs of integers, where 1 < N < 700. Each pair of integers is separated by one blank and ended by a new-line character. The list of pairs is ended with an end-of-file character. No pair will occur twice. 
The input ends with a case which N is equal to zero

Output:

The output consists of one integer representing the largest number of points that all lie on one line.

Sample Input:

5
1 1
2 2
3 3
9 10
10 11
0

Sample Output:

3

      1)第一次看到这道acm题,就没有多想,直接暴力方法,直接取两点确定一条直线,然后再验证其他点是否在直线上。这种暴力而笨拙的方法当然在3S内无法运行完。

代码如下

/*This Code is Submitted by Neil1995 for Problem 1099 at 2014-10-30 07:48:54*/
#include <iostream>
using namespace std;
//暴力求解法
struct Point{
        double x;
        double y;
}point[700];
struct line{
        double A;
        double B;
        double C;
};//一条直线的Ax+By+C=0式子

void GetLine(double &A,double &B,double &C,Point point1,Point point2){
        if(point1.x==point2.x){
                B=0;
        }else{
                B=-1;
        }
        if(point1.x!=point2.x){
                A=(point1.y-point2.y)/(point1.x-point2.x);
        }else{
                A=1;
        }
        C=-A*point1.x+point1.y;
        //A=k.C=-k*x1+y1,B=-1;
        //k=(y1-y2)/(x1-x2);
}

int main(){
        int N;
        int i,j,k;
        int max=0;//直线所包含的最大点个数
        int sum;
        line aline;
        while(cin>>N){
                max=0;
                if(N==0){
                        break;
                }
                for(i=0;i<N;i++){
                        cin>>point[i].x>>point[i].y;
                }
                for(i=0;i<N;i++){
                        for(j=i+1;j<N;j++){
                                sum=0;
                                //A=1.0,B=1.0,C=1.0;
                                aline.A=1.0,aline.B=1.0,aline.C=1.0;
                                GetLine(aline.A,aline.B,aline.C,point[i],point[j]);
                                for(k=0;k<N;k++){
                                        if(aline.A*point[k].x+aline.B*point[k].y+aline.C==0){
                                                sum++;
                                        }
                                }
                                if(sum>max)
                                        max=sum;
                        }
                }
                if(N==1){
                        max=1;
                }
                cout<<max<<endl;
        }
        return 0;
}

2)而后经过查阅互联网,得出第二种方法。首先计算每个点的斜率,然后将某点斜率进行排序,得到该序列上斜率相同最大的长度。(如1,2,2,2,3,4,4,5这串序列,那么最大长度则为3)。对每个点如是计算,得出所有点中最大的长度,即使所求。

/*This Code is Submitted by Neil1995 for Problem 1099 at 2014-10-30 09:09:03*/
#include <iostream>
#include <algorithm>
using namespace std;
struct points{
        double x;
        double y;
}Point[700];

double slope[700];//斜率

int MaxCount(int N);
double Slope(points point1,points point2);

int main(){
        int N;
        int i,j,k;
        int sum;
        int max;
        while(cin>>N){
                if(N==0)
                        break;
                for(i=0;i<N;i++){
                        cin>>Point[i].x>>Point[i].y;
                }
                max=0;
                for(i=0;i<N;i++){
                        //计算i点与所有点连接而成的斜率
                        for(j=i+1,k=0;j<N;j++,k++){     
                                        slope[k]=Slope(Point[i],Point[j]);
                        }
                        sort(slope,slope+k);
                        sum=MaxCount(N);
                        if(sum>max)
                                max=sum;
                        
                }
                cout<<max<<endl;
        }
        return 0;
}

int MaxCount(int N){
        int i;
        int count;
        int maxCount=0;
        count=1;
        for(i=1;i<N-1;i++){
                if(slope[i-1]==slope[i]){
                        count++;
                }else{
                        if(count>maxCount){
                                maxCount=count;
                        }
                        count=1;
                }
        }
        if(count>maxCount){
                        maxCount=count;
        }
        return maxCount+1;
}

double Slope(points point1,points point2){
        double slope;
        if(point1.x==point2.x)
                slope=1000000;
        slope=(point1.y-point2.y)/(point1.x-point2.x);
        return slope;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值