poj 1113 Wall

Address:http://poj.org/problem?id=1113

题目意思: 本题目给你N,L,N代表有这个城堡有N个点组成,L是你现在建的墙离城堡的最小距离。  题解 :求出凸包 凸包的周长  加上 以L 为半径的圆周长

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;

#define PI acos(-1.0)

struct point
{
	double x, y;
}pnt[1010],res[1010];
double dis(point a,point b) {
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool mult(point sp, point ep, point op){
	return (sp.x - op.x) * (ep.y - op.y)>= (ep.x - op.x) * (sp.y - op.y);
}
bool operator < (const point &l, const point &r){
	return l.y < r.y || (l.y == r.y && l.x < r.x);
}
int graham(int n)
{
	int i, len, k = 0, top = 1;
	sort(pnt, pnt + n);
	if (n == 0) return 0; res[0] = pnt[0];
	if (n == 1) return 1; res[1] = pnt[1];
	if (n == 2) return 2; res[2] = pnt[2];
	for (i = 2; i < n; i++) {
		while (top && mult(pnt[i], res[top], res[top-1]))
			top--;
		res[++top] = pnt[i];
	}
	len = top; res[++top] = pnt[n - 2];
	for (i = n - 3; i >= 0; i--) 
	{
		while (top!=len && mult(pnt[i], res[top],res[top-1])) 
			top--;
		res[++top] = pnt[i];
	}
	return top;
}
int main()
{
	int n,i;
	double L;
	while(cin>>n>>L)
	{
		for(i=0;i<n;i++)
			cin>>pnt[i].x>>pnt[i].y;
		int top=graham(n);
		res[top]=res[0];
		double sum=0;
		for(i=0;i<top;i++)
			sum+=dis(res[i],res[i+1]);
		sum+=2*PI*L;
		sum+=0.5;
		cout<<(int)sum<<endl;
	}
	return 0;
}


 

这个代码 时间上有点长。

下面看了一大牛的。

 16MS

 

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
using namespace std;

#define eps 1e-8
#define MAXN 1010
#define INF 1<<30
#define PI 3.1415926
#define zero(x) (((x)>0?(x):-(x)) < eps)




struct point
{
    int x,y;
};
point p[MAXN];
int astack[MAXN];
int cnt;

int xmult(point p1,point p2,point p0)
{
    return (p1.x - p0.x) * (p2.y - p0.y) - (p1.y - p0.y) * (p2.x - p0.x);
}

int dis(point p1,point p2)
{
   // cout<<(p1.x - p2.x) * (p1.x - p2.x)<<' ';
    //cout<<(p1.y - p2.y) * (p1.y - p2.y)<<endl;
    return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y);
}

 

bool cmp(const point &a,const point &b)
{
    int temp = xmult(a,b,p[0]);
    if (temp > eps)
        return true;
    if (zero(temp) && (dis(a,p[0])) < (dis(b,p[0])))
        return true;
    return false;
} 
//极角排序
void Graham(point p[],int n)
{
    int lowpos = 0,minvalue = INF;
	int i;
    for(i = 1;i < n;++i)
    {
        if(p[lowpos].x >= p[i].y && p[lowpos].y >= p[i].y)
            lowpos = i;
    }
    swap(p[0],p[lowpos]);
    sort(p+1,p+n,cmp);
    //用栈去存当前凸包的顶点

    astack[0] = 0;
    astack[1] = 1;
    cnt = 1;
    for(i = 2;i < n;++i)
    {
        //在左边,直接放去栈中
        //cout<<(xmult(p[i],p[astack[cnt]],p[astack[cnt-1]]))<<endl;
        if ((xmult(p[i],p[astack[cnt]],p[astack[cnt-1]])) <= 0 )
            astack[++cnt] = i;
        else
        {
            do
            {
                cnt--;
            }while(xmult(p[i],p[astack[cnt]],p[astack[cnt-1]]) > 0);
            astack[++cnt] = i;
        }
    }

}


int main ()
{
    int n,l,i;
    scanf("%d%d",&n,&l);
    for(i = 0;i < n;++i)
        scanf("%d%d",&p[i].x,&p[i].y);
    Graham(p,n);
    //for(int i = 0;i <= cnt;++i)
    //printf("%d %d\n",p[astack[i]].x,p[astack[i]].y);
    double sum = 0;
    for(i = 0;i < cnt;++i)
    {
        sum += sqrt(dis(p[astack[i]],p[(astack[i+1])]) * 1.0);
        //printf("%lf\n",sum);
    }
    sum += sqrt(dis(p[astack[0]],p[astack[cnt]])*1.0);
    //printf("%lf\n",sum);
    sum += PI* 2 * l+0.5;
    printf("%d\n",(int)sum);
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值