题目链接
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
", res[i].x, res[i].y);
74 }
75 }
76 return 0;
77 }