acm 2036

题目如下:

改革春风吹满地

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 18321    Accepted Submission(s): 9365

Problem Description
“ 改革春风吹满地, 不会AC没关系; 实在不行回老家, 还有一亩三分地。 谢谢!(乐队奏乐)”
话说部分学生心态极好,每天就知道游戏,这次考试如此简单的题目,也是云里雾里,而且,还竟然来这么几句打油诗。
好呀,老师的责任就是帮你解决问题,既然想种田,那就分你一块。 这块田位于浙江省温州市苍南县灵溪镇林家铺子村,
多边形形状的一块地,原本是linle 的,现在就准备送给你了。不过,任何事情都没有那么简单,你必须首先告诉我这块地到底有多少面积,
如果回答正确才能真正得到这块地。 发愁了吧?就是要让你知道,种地也是需要AC知识的!以后还是好好练吧...
 
 

 

Input
输入数据包含多个测试实例,每个测试实例占一行,每行的开始是一个整数n(3<=n<=100),它表示多边形的边数(当然也是顶点数),
然后是按照逆时针顺序给出的n个顶点的坐标(x1, y1, x2, y2... xn, yn),为了简化问题,这里的所有坐标都用整数表示。 输入数据中所有
的整数都在32位整数范围内,n=0表示数据的结束,不做处理。
 

 

Output
对于每个测试实例,请输出对应的多边形面积,结果精确到小数点后一位小数。 每个实例的输出占一行。
 

 

Sample Input
3 0 0 1 0 0 1
4 1 0 0 1 -1 0 0 -1 0
3 0 0 0 1 1 0
 

 

Sample Output
0.5
2.0
-0.5
 

 

需要注意一下几点:

1.题目中没有强调是凹还是凸的三角形(故不适合用一般分解三角形法来做);

2.按照逆时针顺序给出的n个顶点的坐标(故计算的结果不加绝对值)

 

相关知识:

原理介绍

       上书中给出定理:

任意多边形的面积可由任意一点与多边形上依次两点连线构成的三角形矢量面积求和得出。

       矢量面积=三角形两边矢量的叉乘。

       如下图:

按定理,多边形面积由P点与A-G的各顶点连接所构成的三角形矢量面积构成,假定多边形顶点坐标顺序为A-G,逆时针为正方向,则有如下结论:

PAB,PBC,PCD均为顺时针,面积为负;

PDE,PEF,PFG,PGA均未逆时针,面积为正;

但无论正负,均可通过P点与顶点连线的矢量叉乘完成,叉乘结果中已包含面积的正负。

引用:http://www.cnblogs.com/vbspine/archive/2013/03/28/2987818.html

故可以通过矢量叉乘运算

//二维的情况,假设三个顶点坐标分别为(x[i], y[i]), (x[j], y[j]), (x[k], y[k])
double areaTri_2dimension(int i, int j, int k)
{
 double x1 = x[j] - x[i];
 double y1 = y[j] - y[i];
 double x2 = x[k] - x[i];
 double y2 = y[k] - y[i];
 return 0.5 * (x1 * y2 - y1 * x2);
}
 
故最终代码如下:
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <math.h>
 4 
 5 struct Point
 6 {
 7     int x;
 8     int y;
 9 };
10 
11 //以(0,0)点为基准点
12 double AreaS(Point p1,Point p2)
13 {
14     return (p1.x * p2.y - p2.x * p1.y) / 2.0;
15 
16 }
17 
18 int main()
19 {
20     int num;
21     double S;
22     Point * p;
23     while(scanf("%d",&num) && num != 0)
24     {
25          S = 0;
26          p = (Point*)malloc(sizeof(Point) * num);
27         for(int i = 0; i < num ;i++)
28         {
29             scanf("%d %d",&(p[i].x), &(p[i].y));
30         }
31         for(int i = 0; i + 1 < num ;i++)
32         {
33             S += AreaS(p[i],p[i+1]);
34         }
35         S += AreaS(p[num - 1],p[0]);
36         printf("%0.1f\n" ,S);
37     }
38 
39 }

 

posted @ 2014-07-21 21:29  丁香树  阅读(295)  评论(0)    收藏  举报