首页 > 代码库 > COGS 896. 圈奶牛

COGS 896. 圈奶牛

凸包,,,,,,,神奇的凸包2333

本蒟蒻弱势围观了一下Gamham扫描线法,,,

找出左下点,然后把其他点按极角序排一下(极角序相同的可以删掉短的,当然也可以吧短的排到前面)

然后拿一个栈,把新元素压到栈里之前,看看(设栈顶为top)top,top-1和新加入点是不是符合,然后判断一下是不是top点不能再凸包上,然后while搞下去就好了。。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<map>
 6 #define N 100005
 7 #define eps 1e-8
 8 using namespace std;
 9 int n,top;
10 double ans;
11 struct point{double x,y;}p[N],s[N];
12 double dis(point a, point b)
13 {
14     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
15 }
16 double mul(point p1, point p2, point p0)
17 {
18     return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
19 }
20 bool cmp(point a, point b)
21 {
22     if (mul(a,b,p[0])==0) return dis(a,p[0])<dis(b,p[0]);
23     return mul(a,b,p[0])>0;
24 }
25 void Graham()
26 {
27     top=2; point t;
28     int k=0;
29     for (int i=1;i<n; i++)
30         if (p[k].y>p[i].y || (p[k].y==p[i].y && p[k].x>p[i].x)) k=i;
31     t=p[0]; p[0]=p[k]; p[k]=t;
32     sort(p+1,p+n,cmp);
33     s[0]=p[0]; s[1]=p[1]; s[2]=p[2];
34     for (int i=3; i<n; i++)
35     {
36         while (top && mul(p[i],s[top],s[top-1])>=0) top--;
37         s[++top]=p[i];
38     }
39     s[++top]=p[0];
40     for (int i=0; i<top; i++)
41         ans+=dis(s[i],s[i+1]);
42 }
43 int main()
44 {
45     freopen("fc.in","r",stdin);
46     freopen("fc.out","w",stdout);
47     scanf("%d",&n);
48     for (int i=0; i<n; i++)    
49         scanf("%lf%lf",&p[i].x,&p[i].y);
50     Graham();
51     printf("%.2lf",ans);
52     return 0;
53 }

 

COGS 896. 圈奶牛