HDU 2108 Shape of HDU
地址:http://acm.hdu.edu.cn/showproblem.php?pid=2108
解题思路:叉乘的运用
原理是在平面上取(0,0)来分割多边形为多个三角形,然后用叉乘来求三角形的面积(有向)再求和。这样的话可以把凸N多边形转化为N个三角形,然后求解N个三角形即可,输入顶点的顺序 无论是顺时针还是逆时针均可。
* 题目要求:计算多边形面积
* 方法:把n多边形分割成n-2个三角形,分别求和,然后相加
* 注意:分割的所有三角形有一个公共的顶点,这里选择0点位公共点
* 注:题中给出的点的顺序为逆时
* 叉乘的性质:设两向量P和Q
* 1.P ×Q > 0 则Q在P的逆时针方向
* 2.P ×Q < 0 则Q在P的顺时针方向
* 3.P ×Q = 0 则Q和P共线,方向可能相同也可能不相同
参考资料:计算几何基础
之所以不用海伦公式:有一个三角形,边长分别为a、b、c,三角形的面积S可由以下公式求得:S=√[p(p-a)(p-b)(p-c)] 而公式里的p为半周长: p=(a+b+c)/2
是由于1:计算量大。2:精度损失
1 # include <stdio.h> 2 typedef struct POINT{ 3 int x, y ; 4 }point ; 5 point pt[1010] ; 6 int n ; 7 int direction (int x1, int y1, int x2, int y2) 8 { 9 return x1*y2 - x2*y1 ; 10 } 11 int test () 12 { 13 int i ; 14 pt[n] = pt[0], pt[n+1] = pt[1] ; 15 for (i = 2 ; i <= n+1 ; i++) 16 if (direction ( pt[i-1].x-pt[i-2].x, 17 pt[i-1].y-pt[i-2].y, 18 pt[i].x-pt[i-1].x, 19 pt[i].y-pt[i-1].y) < 0 ) 20 return 0 ; 21 return 1 ; 22 } 23 int main () 24 { 25 int i ; 26 while (~scanf ("%d", &n) && n) 27 { 28 if (n > 1000) while (1) ; 29 for (i = 0 ; i < n ; i++) 30 scanf ("%d%d", &pt[i].x, &pt[i].y) ; 31 puts (test() ? "convex" : "concave") ; 32 } 33 return 0 ; 34 }