您的位置:首页 > 其它

POJ1113——WALL 凸包

2017-04-18 15:41 429 查看
调了两个小时(吐

poj1113

凸包有毒啊???

我闲的蛋疼用了一个函数叫atan2

然而这个东西用法有点神奇。。是用来求极角的

atan2(y,x) 注意是y,x 得到的是(x,y)点对对于0,0的弧度!注意是弧度!

弧度转化角度:

#define atan2(x,y) atan2(x,y)*180/3.1415926535


当然其实这题。。不转化角度也没关系,显然弧度与角度是增函数的关系没毛病啊

凸包过程:

1、找到点中左下角(先下,再左)的点,以它为原点

2、求出所有点的极角

3、按照极角排序

4、维护一个栈,保持凸多边形性质,即新加入的点不能在原先的边的右侧

5、完了。

这里我判断是否在右侧是用叉积(因为刚学)

其实也可以直接用解析式判断,具体不细讲

接下来说一下这个题的几个坑点….

1、角度要开double=_=

好吧这个是我傻逼了

2、共线情况要先按纵坐标从小到大排序,再按横坐标从大到小排序

画图理解一下就行,横坐标。。实际上是一样的。。。。

CODE:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<string>
#include<map>
#include<cstring>
#include<vector>
#define inf 1e9
#define ll long long
#define atan2(x,y) atan2(x,y)*180/3.1415926535
#define For(i,j,k) for(ll i=j;i<=k;i++)
#define Dow(i,j,k) for(ll i=k;i>=j;i--)
using namespace std;
struct point
{
int  x,y;
double aph;
}a[2001];
int n;
int d;
int sta[5001];
inline bool cmp(point t1,point t2)
{
if(t1.aph!=t2.aph)return t1.aph<t2.aph;
if(t1.y!=t2.y) t1.y<t2.y;
return t1.x<t2.x;
}
inline double sqr(double x)
{
return x*x;
}
int main()
{
scanf("%d%d",&n,&d);
int t=0;
a[0].y=1e9;
For(i,1,n)
{
scanf("%d%d",&a[i].x,&a[i].y);
if(a[i].y<a[t].y||(a[i].y==a[t].y&&a[i].x<a[t].x))
t=i;
}
swap(a[t],a[1]);
For(i,2,n)  a[i].x-=a[1].x,a[i].y-=a[1].y;
a[1].x=a[1].y=0;
For(i,1,n)
a[i].aph=atan2(a[i].y,a[i].x);
sort(a+2,a+n+1,cmp);
sta[1]=1;sta[2]=2;
int top=2;
For(i,3,n)
{
while(1)
{
int p1=sta[top],p2=sta[top-1];
int S=(a[p1].x-a[p2].x)*(a[i].y-a[p2].y)-(a[i].x-a[p2].x)*(a[p1].y-a[p2].y);
if(S<0)
top--;else break;
}
sta[++top]=i;
}
double  ans=0;
For(i,1,top)
ans+=sqrt(sqr((double)a[sta[i%top+1]].x-(double)a[sta[i]].x)+sqr((double)a[sta[i%top+1]].y-(double)a[sta[i]].y));

ans+=3.1415926*(double)d*2.00;
printf("%.0f\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj