题目中特别说明注意高效,估计简单的O(n^3)枚举法要超时,试了下果然。
不过这个题目以前在上普林斯顿的algorithms里有个大程跟这个95%相似的问题,所以我一下子就想到了优化的解法,复杂度是O( (n^2)logn )。
优化解法:对于每个点,按照其他点相对于这个点的斜率排序,在排序的序列中找寻最长的斜率相同的子串长度,其中最费时的是排序,所以总体的复杂度就是n 乘以 nlogn。
#include<stdio.h>
#include<stdlib.h>
#include<float.h>
#include<string.h>
#define MAX 700+5
typedef struct Point {
int x;
int y;
} Point;
Point points[MAX];
Point cur;
double slope(Point*a) {
int x0 = cur.x;
int y0 = cur.y;
int x1 = a[0].x;
int y1 = a[0].y;
if (x0 == x1 && y0 == y1)
return -DBL_MAX ;
else if (x0 == x1)
return DBL_MAX ;
else if (y0 == y1)
return 0;
else
return 1.0 * (y1 - y0) / (x1 - x0);
}
int cmp(const void*a, const void*b) {
Point*aa = (Point*) a;
Point*bb = (Point*) b;
double sa = slope(aa);
double sb = slope(bb);
if (sa < sb)
return -1;
else if (sa > sb)
return 1;
else
return 0;
}
int calcu2(int n) {
int max = 2;
int i;
for (i = 0; i < n; i++) {
int num = 2;
memcpy(&cur, &points[i], sizeof(Point));
qsort(points, n, sizeof(points[0]), cmp);
int j;
double oldSlope = 0;
for (j = 0; j < n; j++) {
double curSlope = slope(&points[j]);
if (curSlope == oldSlope) {
num++;
if (num > max)
max = num;
} else {
oldSlope = curSlope;
num = 2;
}
}
}
return max;
}
int main() {
int cases;
int len;
scanf("%d", &cases);
getchar();
getchar();
while (cases--) {
int i = 0;
char tmp[200];
while (1) {
if(gets(tmp)==NULL)
break;
if (tmp[0] == 0)
break;
else {
sscanf(tmp, "%d%d", &points[i].x, &points[i].y);
i++;
}
}
len = calcu2(i);
printf("%d\n", len);
if (cases)
printf("\n");
}
return 0;
}