题目:https://cn.vjudge.net/problem/HDU-2108
题意:给一个多边形点的坐标,输入按逆时针排序,判断多边形的凹凸性。
思路:
方法一:求凸包,比较顶点数是否相等。
方法二:根据凸多边形定义:
(1)对于每一条边,其余的边都在该边同一侧。
(2)多边形内角都小于180度。
也就是说对于逆时针排序的边,下一条边必定在上一条边左侧。
实现上可以用叉积判断,向量v1和v2的叉积小于零时,v2在v1左侧。
代码:C++
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#include <stack>
#include <string>
#include <vector>
#include <cstdlib>
using namespace std;
const double eps = 1e-10;
int dcmp(double a)
{
if(fabs(a) < eps)
{
return 0;
}
return a < 0 ? -1 : 1;
}
struct Point
{
double x, y;
Point(double xx = 0, double yy = 0) : x(xx), y(yy) {}
};
typedef Point Vector;
Vector operator - (Point p1, Point p2)
{
return Vector(p2.x - p1.x, p2.y - p1.y);
}
double Cross(Vector v1, Vector v2)
{
return v1.x * v2.y - v1.y * v2.x;
}
int n;
//输入多边形,顶点逆时针顺序排列
bool isConvex(vector<Point> &p)
{
int n = p.size();
if(dcmp(Cross(p[n-1] - p[0], p[1] - p[0]) >= 0))
{
return false;
}
if(dcmp(Cross(p[n - 2] - p[n - 1], p[0] - p[n - 1]) >= 0))
{
return false;
}
for(int i = 1; i < n - 1; i++)
{
if(dcmp(Cross(p[i - 1] - p[i], p[i + 1] - p[i])) >= 0)
{
return false;
}
}
return true;
}
vector<Point> p;
int main()
{
while(scanf("%d", &n) != EOF && n)
{
p.clear();
for(int i = 0; i < n; i++)
{
double x, y;
scanf("%lf%lf", &x, &y);
p.push_back(Point(x, y));
}
printf("%s\n", isConvex(p) ? "convex" : "concave");
}
return 0;
}