题目大意:
让你逆时针输入一个n边行n个点的坐标,然后判断这个n边形的凹凸性。
解题思路:
利用两向量的叉积就可以秒掉。不过一开始对叉积理解得还不是很好。所以调试了20分钟,汗!~~水!~~~
再看一遍叉积吧:
计算矢量叉积是与直线和线段相关算法的核心部分。设矢量P = ( x1, y1 ),Q = ( x2, y2 ),则矢量叉积定义为由(0,0)、p1、p2和p1+p2所组成的平行四边形的带符号的面积,即:P × Q = x1*y2 - x2*y1,其结果是一个标量。显然有性质 P × Q = - ( Q × P ) 和 P × ( - Q ) = - ( P × Q )。一般在不加说明的情况下,本文下述算法中所有的点都看作矢量,两点的加减法就是矢量相加减,而点的乘法则看作矢量叉积。
叉积的一个非常重要性质是可以通过它的符号判断两矢量相互之间的顺逆时针关系:
若 P × Q > 0 , 则P在Q的顺时针方向。
若 P × Q < 0 , 则P在Q的逆时针方向。
若 P × Q = 0 , 则P与Q共线,但可能同向也可能反向。
这里已经很明确地说,如果两个向量P x Q>0,是表明P在Q的顺时针方向。则说明如果一个多边形它是凸多边形的话,那么每两条边之间的叉积必定都是正的,因为逆时针输入数据,所以求出来的向量也都是按逆时针排列回去的。P x Q,凸多边形的话,那么P必定就处于Q的顺时针方向,这时候结果就是正的。用一个for循环判断,如果有一个叉积为负值,那么这个多边形是凹的。
代码:
#include
const int MAX=105;
using namespace std;
typedef struct point
{
double x;
double y;
point(double a=0,double b=0) :x(a),y(b) {}
}P;
typedef struct vet
{
double x;
double y;
}V;
P po[MAX];
V vet[MAX];
int n;
void toVet()
{
for(int i=0;i>n,n)
{
for(i=0;i>po[i].x>>po[i].y;
toVet();
if(isConvex())
cout<<"concave"<