描述
“不要问我太阳有多高
我会告诉你我有多真
不要问我星星有几颗
我会告诉你很多很多”
一天Qinz和wudired在天上数星星,由于星星可以排列成一条直线,他们比赛看谁能找到一条直线使得这条直线上的星星最多。假设夜空是一个二维平面坐标系,坐标轴为x,y。星星的坐标(x,y)为整数,且同一位置至多有一颗星星。他们需要你的帮助,一条直线最多可以穿过多少颗星星(直线不必平行于坐标轴)?
Input
多组数据,EOF结束。
第一行N(0<=N<=1000)为天上星星的数量。
接下来N行每行两个数字 X,Y(0<=X,Y<=10^9),表示星星的位置。以空格分开。
Output
输出一行,表示一条直线最多穿过多少颗星星。
Sample Input
3
1 1
2 2
3 3
Sample Output
3
解题思路:
开始没有想到怎么解决这个问题,最后还是从网上参考的答案。
两个点可以确定一条直线,那么N个点共有N×(N-1)条直线,那么怎么判断那些直线共线呢?
共线的直线有这样的特点:有一个相同的点,且斜率相同。所以可以设计这样的算法:
(1)如果点小于3,直接输出点数为结果
(2)以第一个为共同点
(3)计算其他点与它组成直线的斜率
(4)对斜率排序,统计其中斜率连续相同的最大数stars,并根据它相应个性最大Max
(5)以下一个点为共同点,转向(3)
(6)输出Max
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
using namespace std;
bool lessK(const double &r1,const double &r2)
{
return r1<r2;
}
int main()
{
int N;
const int MaxN =1000;
int x[MaxN],y[MaxN];
vector<double> line;
vector<double>::iterator iter;
while(cin>>N)
{
if(N<3)
{
cout<<N<<endl;
continue;
}
int maxStar = 2;
for(int i=0;i<N;++i)
{
cin>>x[i]>>y[i];
}
for(int i=0;i<N-1;++i)
{
line.clear();
for(int j=i+1;j<N;++j)
{
double k;
if(x[j]==x[i])
k = 1E10;
else k = double(y[j]-y[i])/(x[j]-x[i]);
line.push_back(k);
}
sort(line.begin(),line.end(),lessK);
int stars = 2;
for(iter=line.begin()+1;iter!=line.end();++iter)
{
if(fabs(*iter-*(iter-1)<1E-10))
{
++stars;
if(stars>maxStar)
maxStar = stars;
}
else
{
stars = 2;
}
}
}
cout<<maxStar<<endl;
}
return 0;
}
最后欢迎大家访问我的个人网站: 1024s