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

216人阅读 评论(0)

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;
}

0
0

个人资料
• 访问：13892次
• 积分：884
• 等级：
• 排名：千里之外
• 原创：76篇
• 转载：2篇
• 译文：0篇
• 评论：3条
阅读排行