http://acm.hdu.edu.cn/showproblem.php?pid=2036
改革春风吹满地
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 42169 Accepted Submission(s): 21613
不会AC没关系;
实在不行回老家,
还有一亩三分地。
谢谢!(乐队奏乐)”
话说部分学生心态极好,每天就知道游戏,这次考试如此简单的题目,也是云里雾里,而且,还竟然来这么几句打油诗。
好呀,老师的责任就是帮你解决问题,既然想种田,那就分你一块。
这块田位于浙江省温州市苍南县灵溪镇林家铺子村,多边形形状的一块地,原本是linle 的,现在就准备送给你了。不过,任何事情都没有那么简单,你必须首先告诉我这块地到底有多少面积,如果回答正确才能真正得到这块地。
发愁了吧?就是要让你知道,种地也是需要AC知识的!以后还是好好练吧...
输入数据中所有的整数都在32位整数范围内,n=0表示数据的结束,不做处理。
每个实例的输出占一行。
点乘与叉乘:
点:A(x1,y1),B(x2,y2)
向量:向量AB=( x2 - x1 , y2 - y1 )= ( x , y );
向量的模 |AB| = sqrt ( x*x+y*y );
点乘的: 结果为 x1*x2 + y1*y2。
点积的结果点积是一个数值。
点积的集合意义:我们以向量 a 向向量 b 做垂线,则 | a | * cos(a,b)
为 a 在向量 b 上的投影,即点积是一个向量在另一个向量上的投影乘以另一个向量。且满足交换律
应用:可以根据集合意义求两向量的夹角,
cos(a,b) =( 向量a * 向量b ) / (| a | * | b |)
= x1*x2 + y1*y2 / (| a | * | b |)
向量的叉积: 结果为 x1*y2-x2*y1
叉积的结果也是一个向量,是垂直于向量a,b所形成的平面,如果看成三维坐标的话是在 z 轴上,上面结果是它的模。
方向判定:右手定则,(右手半握,大拇指垂直向上,四指右向量a握向b,大拇指的方向就是叉积的方向)
叉积的集合意义:
1:其结果是a和b为相邻边形成平行四边形的面积,为a.b为邻边的三角形面积的二倍。
2:结果有正有负,有sin(a,b)可知和其夹角有关,夹角大于180°为负值。
3:叉积不满足交换律
应用:
1:通过结果的正负判断两矢量之间的顺逆时针关系
若 a x b > 0表示a在b的顺时针方向上
若 a x b < 0表示a在b的逆时针方向上
若 a x b == 0表示a在b共线,但不确定方向是否相同
2:判断折线拐向,可转化为判断第三点在前两的形成直线的顺逆时针方向,然后判断拐向。
3:判断一个点在一条直线的那一侧,同样上面的方法。
4:判断点是否在线段上,可利用叉乘首先判断是否共线,然后在判断是否在其上。
5:判断两条直线是否想交(跨立实验)
根据判断点在直线那一侧我们可以判断一个线段的上的两点分别在另一个线段的两侧,当然这是不够的,因为我们画图发现
这样只能够让直线想交,而不是线段,所以我们还要对另一条线段也进行相同的判断就ok。
如何求多边形的面积?
S = 1/2×((X1*Y2-X2*Y1) + … + ( Xk*Yk+1-Xk+1*Yk )+ ... + ( Xn*Y1-X1*Yn))
需要注意的是,如果一系列点按逆时针排列算出的是正面积,而如果是顺时针的话算出的则是一个负面积
#include <iostream> #include <cmath> #include <cstdio> using namespace std; int main(){ int n; int x[305], y[305]; double area = 0; while(cin >> n && n){ area = 0; for(int i = 0; i < n; i++){ cin >> x[i] >> y[i]; } for(int i = 1; i < n; i++){ area += (x[i - 1] * y[i] - x[i] * y[i - 1]) / 2.0; } area += (x[n - 1] * y[0] - x[0] * y[n - 1]) / 2.0; //最后一个点和第一个点,这样才构成封闭的多边形 // cout << area << endl; printf("%.1lf ", abs(area)); } return 0; }