题目:http://ac.jobdu.com/problem.php?pid=1548
题意:给出平面上n个点,问最多有多少个点能在一条直线上。
思路:数据很小,三重循环暴力即可。但是需要注意循环范围的优化。
两向量叉积为0,代表两向量共线,通过此法判别三点共线。
二维平面叉积:a×b=|a||b|sinθ 方向垂直于两向量组成的平面,符合右手法则。
坐标表示a×b=(axbx-ayby)k
另外需要注意,有可能两个不同的点坐标相同。
根据我的错误记录,估计该题目的第四组数据应该是所有点的坐标都相同。
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <string.h>
using namespace std;
#define MOD 1000000007
//typedef __int64 LL;
struct Point{
int x, y;
};
inline int xmult(Point p1, Point p2, Point p0){
return (p1.x - p0.x)*(p2.y - p0.y) - (p2.x - p0.x)*(p1.y - p0.y);
}
Point p[105];
int main(){
freopen("in.txt", "r", stdin);
int n, i, j, k;
int res, t;
while (scanf("%d", &n) != EOF){
for (i = 0; i < n; i++)
scanf("%d%d", &p[i].x, &p[i].y);
if (n == 0 || n == 1 || n == 2){
printf("%d\n", n);
continue;
}
res = -1;
for (i = 0; i < n; i++)
for (j = i + 1; j < n; j++){
t = 2;
while (j < n &&p[i].x == p[j].x &&p[i].y == p[j].y){
t++;
j++;
}
if (j == n)
t--;
for (k = 0; k < n; k++){
if (k >= i&&k <= j)
continue;
if (!xmult(p[i], p[j], p[k]))
t++;
}
if (t>res)
res = t;
}
printf("%d\n", res);
}
}