凸包郁闷死我了
计算机 c/c++ OI 凸包 算法 编程
郁闷啊郁闷,写了两个凸包的题目,都折戟在一两个NB数据上了。 tyvj上P1462的程序,赤果果的求凸包。自己写的Graham扫描法,极角顺序,从最下最右的点开始: #include <stdio.h> #include <stdlib.h> #include <math.h> #ifndef M_PI #define M_PI 3.14159265358979323846 #endif typedef struct { double x, y, tg; } coord; // 算极角 inline double calc_tg (const coord b, const coord n) { double ret = atan2(n.y-b.y, n.x-b.x); return ret >= 0 ? ret:ret+2*M_PI; } // 判断是否左转 #define tleft(a,b,c) \ (((b).x-(a).x)*((c).y-(a).y)-((c).x-(a).x)*((b).y-(a).y) <= 0.0) // 快排之比较 int comp (const void *pa, const void *pb) { const coord *a = (const coord*)pa, *b = (const coord*)pb; if (a->tg > b->tg) return 1; else if (a->tg != b->tg) return -1; else return a->x > b->x ? 1:-1; } int main () { int n, i, stktail; coord *p, **stk, minc = {0.0, 1.0E22}; // 读入数据 scanf("%d", &n); p = malloc(n*sizeof(coord)); stk = malloc(n*sizeof(coord*)); for (i=0; i<n; i++) { scanf("%lf %lf", &(p[i].x), &(p[i].y)); if ((p[i].y < minc.y) || ((p[i].y == minc.y) && (p[i].x < minc.x))) minc = p[i]; } // 求凸包 for (i=0; i<n; i++) p[i].tg = calc_tg(minc, p[i]); qsort(p, n, sizeof(coord), comp); stk[0] = p; stk[1] = p+1; stk[2] = p+2; stktail = 2; for (i=3; i<n; i++) { while (stktail >= 1) { coord *base = stk[stktail-1], *last = stk[stktail]; if (tleft(*base, *last, p[i])) stktail--; else break; } stk[++stktail] = p+i; } while (stk[stktail]->tg == stk[stktail-1]->tg) stktail--; // 按要求的顺序输出 int st = 0; double minx = stk[0]->x; for (i=stktail; i>=0; i--) { if (stk[i]->x < minx) minx = stk[i]->x, st = i; else break; } i = st; do { printf("%.4lf %.4lf\n", stk[i]->x, stk[i]->y); if (--i < 0) i = stktail; } while (i != st); return 0; } 运行结果: #01: Accepted (0ms, 196KB) #02: Accepted (0ms, 196KB) #03: Accepted (0ms, 200KB) #04: Accepted (0ms, 196KB) #05: Accepted (0ms, 200KB) #06: Accepted (0ms, 332KB) #07: Accepted (293ms, 2936KB) #08: Wrong Answer (637ms, 2936KB) #09: Accepted (0ms, 224KB) #10: Accepted (0ms, 304KB) #11: Time Limit Exceeded (?, 2388KB) 错的那个可能是精度问题(但我尝试了,long double也过不去,所以也可能是写错了)。 最后一个超时。我已经各种优化了:把C++程序改成C,动态申请内存(不清0了),手动define内联函数,使用double而非long double…… 但还是超时。难道是qsort太慢了? 郁闷啊。可能我的实现比较烂,求神牛指导实现细节。
Page created on 2011-09-10