Graham算法模板

Graham算法模板
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 using namespace std;
 7 typedef long long ll;
 8 const int maxn=1100;
 9 const double pi=acos(-1.0);
10 struct node{
11     double x,y;
12 }p[maxn],a[maxn];
13 int n,tot;
14 
15 //算距离
16 double dis(node a, node b){
17     return hypot(a.x-b.x,a.y-b.y);
18 }
19 
20 //return 正:p2在向量p0p1的左侧;return 负:p2在向量p0p1的右侧;return 0:三点共线
21 double multi(node p0,node p1,node p2){
22     return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
23 }
24 //极角排序:根据坐标系内每一个点与x轴所成的角,逆时针比较,按照角度从小到大排序
25 int cmp(node a, node b){
26     int x=multi(a,b,p[0]);
27     if( x>0 || (x==0&& dis(a,p[0])<dis(b,p[0]))) return 1;
28     return 0;
29 }
30 
31 void Graham(){
32     int k=0;
33     for(int i=1;i<n;i++){
34         if( p[i].y<p[k].y || (p[i].y==p[k].y&&p[i].x<p[k].x)) k=i;
35     }
36     swap(p[0],p[k]);
37     sort(p+1,p+n,cmp);
38     tot=2;
39     a[0]=p[0];
40     a[1]=p[1];
41     for(int i=2;i<n;i++){
42         while( tot>1 && multi(p[i],a[tot-1],a[tot-2])>=0 ){//a[tot-2]在p[i]a[tot-1]的左侧或三点共线,则p[i]在a[tot-2]a[tot-1]的右侧,则a[tot-1]不是极点
43             tot--;
44         }
45         a[tot++]=p[i];
46     }
47 }
48 
49 int main()
50 {
51     int t;
52     scanf("%d",&t);
53     while( t-- ){
54         double r;
55         scanf("%d%lf",&n,&r);
56         for(int i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
57         Graham();
58     }
59     return 0;
60 }

 

 
posted @ 2020-02-12 11:17  swsyya  阅读(210)  评论(0编辑  收藏  举报

回到顶部