poj1113四舍五入的问题

poj1113题目

题目的要求是求一圈建筑物围一圈围墙且围墙离建筑物的距离最小为L,思路是对于一个建筑物的围墙周长最小应该是建筑物的所有点用一个凸包包围后的周长,再加上由于距离最小我注释说c++编译的原因是,这用c++编译器最后AC了,但是我一开始是用g++编译导致一直结果是WA ,主要本地编译器可以自动四舍五入,所以以为问题不会出在这。然后我一直在想自己哪里错了,后来一个有经验的师兄发现我的那样写法在g++可能不会自动四舍五入,换了个写法 printf("%d\n",int(len+0.5));再提交就过了,所以也是吃一堑长一智,还是自己实现四舍五入来的保险,因为不知道到底哪些编译器会帮你实现哪些又不会。大家共勉!(代码写的不好,主要是想和大家分享下这个小经验)成的圆弧将构成一个圆(多边形的外角和为360度,所以所有的围墙上的圆弧刚好是一个圆),因此再加上以L为半径的圆的周长即可。

所以主要是求凸包。用的是Graham,点的排序用极角排序实现。

以下是代码实现。错了好几次后,发现精度问题,也是参考了别人的代码实现了一个解决方法。主要被这道题一直坑的一个点是最后输出要四舍五入,我用的是

  printf("%.0lf\n",len);//c++编译

我注释说c++编译的原因是,这用c++编译器最后AC了,但是我一开始是用g++编译导致一直结果是WA ,主要本地编译器可以自动四舍五入,所以以为问题不会出在这。然后我一直在想自己哪里错了,后来一个有经验的师兄发现我的那样写法在g++可能不会自动四舍五入,换了个写法 printf("%d\n",int(len+0.5));再提交就过了,所以也是吃一堑长一智,还是自己实现四舍五入来的保险,因为不知道到底哪些编译器会帮你实现哪些又不会。大家共勉!(代码写的不好,主要是想和大家分享下这个小经验)

#include <iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<stack>
#define EPS 1e-8
#define PI 3.1415926535897932384626
using namespace std;
struct node{
  double x,y;
  double angle;
  node(double x1,double y1){x=x1,y=y1;}
};
node * nodes[1010],*convex[1010],*n0;
int  n ,l=0,r;
double leftx=10010.0,lefty=10010.0;

double dist(node *n1, node* n2){
   return sqrt( (n1->x - n2->x )* (n1->x - n2->x ) + (n1->y - n2->y )* (n1->y - n2->y ));
}
int sgn(double x)
{
    if (fabs(x) < EPS)
        return 0;
    return x < 0 ? -1 : 1;
}
double direct(node* n1, node *n2,node *n3){
   return (n2->x -n1->x)*(n3->y -n1->y)-(n2->y -n1->y)*(n3->x -n1->x);
}

bool cmp( node  * n1,  node  *n2){
    if(sgn(direct(n0,n1,n2))>0 || ( sgn(direct(n0,n1,n2))==0  && dist(n1,n0)<dist(n0,n2)))
        return true;
     else
        return false;

}

/*double cross_product( node* n1, node *n2,node *n3){
    double x1,y1,x2,y2;
    x1=n2->x - n1->x;
    y1=n2->y - n1->y;
    x2= n3->x - n2->x;
    y2= n3->y - n2->y;
    double s=x1*y2 -y1*x2;
    return s;
}*/
void Graham(){
   l=0;
    convex[l++] = n0;//cout<<convex[0]->x<<" "<<convex[0]->y<<endl;
    for(int i=0;i<n;i++){
            if(nodes[i]->x==leftx && nodes[i]->y==lefty) continue;
        while(l>1&&cross_product(convex[l-2] , convex[l-1] ,nodes[i])<= 0){
            l--;
        }
        convex[l++]=nodes[i];//cout<<nodes[i]->x<<" "<<nodes[i]->y<<endl;
    }
}

double getlength(){
    double len=0.0;//cout<<convex[0]->x<<" "<<convex[0]->y<<endl;
    for(int i=1;i<l ;i++){//cout<<convex[i]->x<<" "<<convex[i]->y<<endl;
        len+=dist(convex[i] ,convex[i-1]);
    }

    len+=dist(convex[l-1] ,convex[0]);
    len+=2*r*PI;
    return len;

}
int main()
{

    scanf("%d%d",&n,&r);
    for(int i=0 ;i<n ;i ++ ){
        nodes[i]=new node(0,0);
        scanf("%lf%lf",&nodes[i]->x,&nodes[i]->y);
        if( nodes[i]->x <leftx || nodes[i]->x == leftx && lefty > nodes[i]->y){//找到左下角的点
            leftx = nodes[i]->x;
            lefty = nodes[i]->y;
        }
    }
    n0=new node(leftx,lefty);
    sort(nodes,nodes+n,cmp);
    Graham();
    double len=getlength();
  //  cout<<len<<endl;
    printf("%.0lf\n",len);//c++编译

    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值