26-多边形的面积(叉乘)

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


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
 
Sample Output
0.5 2.0
 
Author
lcy
 
Source
 
Recommend
lcy   |   We have carefully selected several similar problems for you:  1115 1086 2035 2108 2037 

点乘与叉乘:
点: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\n", abs(area));
	}
	
	return 0;
} 

  

猜你喜欢

转载自www.cnblogs.com/zhumengdexiaobai/p/9230924.html
今日推荐