# 凸包（判多边形的凹凸性）

struct point
{
int x,y;
friend bool operator < (const point &a,const point &b)
{
if (a.y == b.y) return a.x < b.x;
return a.y < b.y;
}
} src[MAXN];
int cost[MAXN][MAXN];
int N,P;
int dp[MAXN][MAXN];

point save[MAXN],tmp[MAXN];
int cross(point p0,point p1,point p2)
{
//cout<<"p0="<<p0.x<<"  "<<p0.y<<"  p1="<<p1.x<<"  "<<p1.y<<"   p2="<<p2.x<<"  "<<p2.y<<endl;
return (p1.x - p0.x) * (p2.y - p0.y) - (p1.y - p0.y) * (p2.x - p0.x);
}

int graphm(point * p,int n)//0-n-1的n个点，放在结构体里面，排序后按照逆序判断各点的凹凸性
{
sort(p,p + n);
save[0] = p[0];
save[1] = p[1];
int top = 1;
for(int i = 0 ; i < n ; i++)
{
while(top && cross(save[top],p[i],save[top-1]) >= 0)
{
//cout<<"top="<<top<<"  i="<<i<<"  top-1="<<top-1<<endl;
top--;
}
save[++top] = p[i];
}

int mid = top;
for(int i = n - 2 ; i >= 0 ; i--)
{
while(top > mid && cross(save[top],p[i],save[top-1]) >= 0)
{
//cout<<"top="<<top<<"  i="<<i<<"  top-1="<<top-1<<endl;
top--;
}
save[++top]=p[i];
}
}

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <set>

using namespace std;
typedef long long ll;

const int MAXN = 310;
struct point
{
int x,y;
friend bool operator < (const point &a,const point &b)
{
if (a.y == b.y) return a.x < b.x;
return a.y < b.y;
}
} src[MAXN];
int cost[MAXN][MAXN];
int N,P;
int dp[MAXN][MAXN];

point save[MAXN],tmp[MAXN];
int cross(point p0,point p1,point p2)
{
//cout<<"p0="<<p0.x<<"  "<<p0.y<<"  p1="<<p1.x<<"  "<<p1.y<<"   p2="<<p2.x<<"  "<<p2.y<<endl;
return (p1.x - p0.x) * (p2.y - p0.y) - (p1.y - p0.y) * (p2.x - p0.x);
}

int graphm(point * p,int n)
{
sort(p,p + n);
save[0] = p[0];
save[1] = p[1];
int top = 1;
for(int i = 0 ; i < n ; i++)
{
while(top && cross(save[top],p[i],save[top-1]) >= 0)
{
//cout<<"top="<<top<<"  i="<<i<<"  top-1="<<top-1<<endl;
top--;
}
save[++top] = p[i];
}

int mid = top;
for(int i = n - 2 ; i >= 0 ; i--)
{
while(top > mid && cross(save[top],p[i],save[top-1]) >= 0)
{
//cout<<"top="<<top<<"  i="<<i<<"  top-1="<<top-1<<endl;
top--;
}
save[++top]=p[i];
}
}

int getcost(point a,point b)
{
return (abs(a.x + b.x) * abs(a.y+b.y)) % P;
}

int main()
{
while (scanf("%d%d",&N,&P) != EOF)
{
for (int i = 0 ; i < N ; i++) scanf("%d%d",&src[i].x,&src[i].y);
int num = graphm(src,N);
if (num < N)
{
printf("I can't cut.\n");
}
else
{
memset(cost,0,sizeof(cost));
for (int i = 0 ; i < N ; i++)
{
for (int j = i + 2 ; j < N ; j++) cost[i][j] = cost[j][i] = getcost(save[i],save[j]);
}
memset(dp,0x3f,sizeof(dp));
for (int i = 0 ; i < N ; i++) dp[i][(i + 1) % N] = 0;//相邻两点费用为0
for(int i=N-3;i>=0;i--)//从倒数第二个点开始枚举
{
for(int j=i+2;j<N;j++)
{
for(int k=i+1;k<j;k++)
{
dp[i][j] = min(dp[i][j],dp[i][k] + dp[k][j] + cost[i][k] + cost[k][j]);
}
}
}
printf("%d\n",dp[0][N - 1]);
}
}
return 0;
}

#### 判断多边形凹凸性

2016-03-01 14:42:34

#### 多边形相关算法(面积、凹凸性、凸包、两多边形相交等)

2008年12月12日 3.44MB 下载

#### ACM--多边形凹凸判断--HDOJ 2108--Shape of HDU

2016-05-26 18:59:31

#### 判断平面多边形的凹凸性

2017-04-14 23:51:15

#### POJ1584 几何 凸包判断 点和多边形的位置关系

2016-08-12 20:05:34

#### 判断点在任意多边形（包括凹凸边形）内

2015-12-26 14:44:23

#### Shape of HDU 几何问题判断多边形凹凸性

2015-09-13 17:52:21

#### matlab 判定多边形顶点凹凸性

2017年10月24日 983B 下载

#### 求多边形或轮廓的凸包（Hull）

2013-03-30 17:41:17

#### opencv学习之寻找凸包，使用多边形包围轮廓

2017-01-30 20:59:31