Lining Up
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!
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
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; }