timus 1052. Rabbit Hunt URAL 解题报告 多点共线问题
以前总是对计算几何很恐惧,慢慢做了几道入门题之后,发现还是挺有意思的!
题目大意:
求多点共线,这样的话猎人就能一次打死好多兔子
思路:
枚举,先找出两点,然后枚举剩下的点有多少共线的…… O(n^3),效率貌似不高,但是很容易A这个200难度的题
改进版,仔细观察上面的算法,比较另外的点是不是在这条直线,其实还是比较斜率,好多斜率貌似求了很多次 ,于是可以枚举i,j然后排序之后判断有多少相邻的斜率一样就好了
注意没有斜率的时候用斜率很大来表示……
两种解法,第一种copy的代码
#include <iostream>
using namespace std;
int main()
{
int i, j, k, max = 0, n, num;
int x[200], y[200];
cin>>n;
for (i=0; i<n; i++)
cin>>x[i]>>y[i];
for (i=0; i<n-1; i++)
{
for (j=i+1; j<n-1; j++)
{
num = 2;
for (k=j+1; k<n; k++)
if ((x[k]-x[i])*(y[j]-y[i]) == (x[j]-x[i])*(y[k]-y[i]))
num++;
if (max < num)
max = num;
}
}
cout<<max<<endl;
}
改进版:
#include <iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const double INF = 1e20;
const double EPS=1e-6;
bool dd(double x,double y) { return fabs( x - y ) < EPS;} // x == y
double getk(double x1,double y1,double x2,double y2)
{
if(dd(x1,x2))return INF;
else return (y2-y1)/(x2-x1);
}
int main()
{///方法er,优化法,因为O(N^3)要有好多次重复的计算,好多次比较斜率的时候实际上是把两点的斜率重新计算了下,
///所以先把i,j的斜率算出来,在做处理
int n, num;
int x[200], y[200];
cin>>n;
for (int i=0; i<n; i++)
cin>>x[i]>>y[i];
double kk[200*200+10];
int tot=0,max=0,tmp=0;
for (int i=0; i<n-1; i++)
{
tot=0;
for (int j=i+1; j<n; j++)
{
kk[tot++]=getk(x[i],y[i],x[j],y[j]);
}
sort(kk,kk+tot);
tmp=2;
for(int j=1;j<tot;++j)
{
if(dd(kk[j],kk[j-1]))tmp++;
}if(tmp>max)max=tmp;
}
cout<<max<<endl;
}