题目中特别说明注意高效,估计简单的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; }