版权声明:转载注明下出处就行了。 https://blog.csdn.net/LJD201724114126/article/details/84111472
题目链接:poj 3348
题意:给出n个点,问能用这n个点最多能围成多少面积,一头牛需要50平方米的地盘,求最多能容纳多少头牛?
题解:直接求这n个点的凸包,最后计算下面积就行了。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=10010;
struct point{
int x,y;
point(){}
point(int _x,int _y){
x=_x;y=_y;
}
}p[maxn],ch[maxn];
point operator + (point a,point b) {return point(a.x+b.x,a.y+b.y);}
point operator - (point a,point b) {return point(a.x-b.x,a.y-b.y);}
point operator * (point a,int p) { return point(a.x*p,a.y*p);}
point operator / (point a,int p){ return point(a.x/p,a.y/p);}
bool operator < (const point &a,const point &b){
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
const double esp=1e-8;
int dcmp(double x){
if(fabs(x)<esp) return 0;
else return x<0?-1:1;
}
bool operator ==(const point &a,const point &b){
return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
int Cross(point a,point b) { return a.x*b.y-a.y*b.x;}
bool cmp(point a,point b){
return a.y<b.y||(a.y==b.y&&a.x<b.x);
}
int tot;
void andrew(int n)
{
sort(p,p+n,cmp);
tot=-1;
for(int i=0;i<n;i++) ///构造凸包下侧
{
while(tot>0&&Cross(ch[tot]-ch[tot-1],p[i]-ch[tot-1])<=0)
tot--;
ch[++tot]=p[i];
}
for(int i=n-2,k=tot;i>=0;i--){ ///构造凸包上侧
while(tot>k&&Cross(ch[tot]-ch[tot-1],p[i]-ch[tot-1])<=0)
tot--;
ch[++tot]=p[i];
}
}
int Area(point *ch,int n) ///叉积求面积
{
int area=0;
for(int i=1;i<n;i++)
area+=Cross(ch[i]-ch[0],ch[i+1]-ch[0]);
return area/2;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
scanf("%d%d",&p[i].x,&p[i].y);
andrew(n);
int item=Area(ch,tot)/50;
printf("%d\n",item);
}
}