nyoj-78-圈水池(Graham算法求凸包)
1 /* 2 Name:nyoj-78-圈水池 3 Copyright: 4 Author: 5 Date: 2018/4/27 9:52:48 6 Description: 7 Graham求凸包 8 zyj大佬的模板,改个输出就能用 9 */ 10 #include <cstring> 11 #include <iostream> 12 #include <cstdio> 13 #include <algorithm> 14 using namespace std; 15 struct point{ 16 double x, y; 17 }; 18 bool mult(point sp, point ep, point op){ //叉积 19 return (sp.x - op.x) * (ep.y - op.y) >= (ep.x - op.x) * (sp.y - op.y); 20 } 21 inline bool operator < (const point &l, const point &r){ 22 return l.y < r.y || (l.y == r.y && l.x < r.x); 23 } 24 int graham(int n, point pnt[], point res[]){ 25 int i, len, top = 1; 26 sort(pnt, pnt + n);//排序找最小的点 27 if (n == 0){ 28 return 0; 29 } 30 res[0] = pnt[0]; 31 if (n == 1){ 32 return 1; 33 } 34 res[1] = pnt[1]; 35 if (n == 2){ 36 return 2; 37 } 38 res[2] = pnt[2]; 39 for (i = 2; i < n; i++){ 40 while (top && mult(pnt[i], res[top], res[top - 1])){ 41 top--; 42 } 43 res[++top] = pnt[i]; 44 } 45 len = top; 46 res[++top] = pnt[n - 2]; 47 for (i = n - 3; i >= 0; i--){ 48 while (top != len && mult(pnt[i], res[top], res[top - 1])){ 49 top--; 50 } 51 res[++top] = pnt[i]; 52 } 53 return top; // 返回凸包中点的个数 54 } 55 bool cmp(const point &l, const point &r){ 56 return l.x < r.x || (l.x == r.x && l.y < r.y); 57 } 58 int main() 59 { 60 int t; 61 cin>>t; 62 point pnt[105], res[105]; 63 while (t--) { 64 memset(res, 0, sizeof(res)); 65 memset(pnt, 0, sizeof(pnt)); 66 int m; 67 cin>>m; 68 for (int i=0; i<m; i++) 69 cin>>pnt[i].x>>pnt[i].y; 70 int ct = graham(m, pnt, res); 71 sort(res, res + ct, cmp); 72 for (int i=0; i<ct; i++) { 73 printf("%.0f %.0f\n", res[i].x, res[i].y); 74 } 75 } 76 return 0; 77 }