POJ3348-Cows-求凸包面积

题意:求给定的n个坐标形成的凸包面积

套公式即可。

从而引入凸包

思路:

本题利用叉乘求面积(选取凸包上的一个点作为基点,然后把多边形分成许多的三角形,然后用叉积去算三角形面积即可)

求解凸包用到的是Andrew算法,Graham算法的变种,速度更快稳定性也更好。

两种算法的复杂度均为O(nlogn),若输入有序的话时间复杂度就均为O(n)

下面介绍Andrew算法:

Andrew算法执行步骤:

1、将所有的点按照横坐标从小到大进行排序,横坐标相同则按纵坐标从小到大排;

2、将P[0]和P[1]加入凸包,然后从P[2]开始判断,判断方式同Graham算法中的判断一致;

3、将所有的点扫描一遍以后,我们便可以得到一个“下凸包”(为什么?画个图就懂了--横坐标不会减小);

4、同理,我们从P[n-2]开始(P[n-1]已经判过了),反着扫描一遍,便可以得到一个“上凸包”;

5、将两个“半凸包”合在一起就是一个完整的凸包,注意的是由于起点P[0]在正着扫描和反着扫描时都会将其加入凸包,故需要将最后一个点(P[0])去掉才为最终结果。

AC代码:

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<string.h>
 5 
 6 using namespace std;
 7 typedef long long ll;
 8 #define inf 0x3f3f3f3f
 9 const int N=10020;
10 
11 struct node
12 {
13     double x,y;
14 }p[N],st[N];
15 int n;
16 
17 double cross(node a,node b,node c)
18 {
19     return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
20 }
21 
22 int cmp(node a,node b)
23 {
24     if(a.x!=b.x)
25         return a.x<b.x;
26     return a.y<b.y;
27 }
28 
29 int Andrew()
30 {
31     sort(p,p+n,cmp);
32     int x=0;
33     for(int i=0;i<n;i++)
34     {
35         while(x>1&&cross(st[x-2],st[x-1],p[i])<=0)
36             x--;
37         st[x++]=p[i];
38     }
39     int k=x;
40     for(int i=n-2;i>=0;i--)
41     {
42         while(x>k&&cross(st[x-2],st[x-1],p[i])<=0)
43             x--;
44         st[x++]=p[i];
45     }
46     return x-1;
47 }
48 
49 int main()
50 {
51     while(~scanf("%d",&n))
52     {
53         memset(st,0,sizeof(st));
54         for(int i=0;i<n;i++)
55             scanf("%lf %lf",&p[i].x,&p[i].y);
56         int ans=0;
57         int x=Andrew();
58         for(int i=1;i<x;i++)
59             ans+=cross(st[0],st[i],st[i+1]);
60         printf("%d\n",ans/100);//ans/2/50
61     }
62     return 0;
63 }
View Code

猜你喜欢

转载自www.cnblogs.com/OFSHK/p/12709020.html