poj1113 凸包
2013-03-10 13:19
274 查看
题目链接:http://poj.org/problem?id=1113
首先注意的是在c或c++中用强制类型转换将浮点型数据转换为int型的时候是只取整数部分的,要进行四舍五入需要在浮点数据上加0.5来进行,这道题就是让我在这里WA了几次,刚开始也有想到,但是没有改,然后在网上搜测试数据,然后就发现还是这样的错误,也罢,吃一堑长一智!
题目大意是给你一个城堡外围转折点的坐标,让你找到一个长度最短的城墙将城堡围起来,而且围墙离城堡的距离最少有l距离的!
大致思路:采用凸包,找到城堡最外围的点,然后围墙的长度就为所有外围的点的距离和加上接点的距离,因为有最小的距离了,就需要生成点a的两条线求其夹角,然后根据圆的周长公式求得,下面是代码:
#include<iostream> #include<cstdio> #include<cmath> #include<stack> using namespace std; #define pi 3.14159265358 typedef struct point { int x,y; }rr; point a[1005],*p; int b[1005]; int n,l; int Sort(point p1,point p2,point p3,point p4) { int t=(p2.x-p1.x)*(p4.y-p3.y)-(p4.x-p3.x)*(p2.y-p1.y); return t; } int distance(point p1,point p2,point p3,point p4) { return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)>(p3.x-p4.x)*(p3.x-p4.x)+(p3.y-p4.y)*(p3.y-p4.y)?1:-1; } int cmp(const void *a,const void *b) { point *c=(point *)a; point *d=(point *)b; int temp=Sort(*p,*c,*p,*d); if(temp<0) return 1; else if(temp==0) return distance(*p,*c,*p,*d); else return -1; } void foud()//将点集合的所有的外边的点找出来 { int i,pc=2; b[1]=0; b[2]=1; b[0]=2;//记录的是总的个数的 for(i=2; ;) { i=i%n;///需要将0的也进行一下再结合 if(i==1) break; if(b[0]==1) { b[++pc]=i++; b[0]++; continue; } if(Sort(a[b[pc-1]],a[b[pc]],a[b[pc]],a[i])<=0)//删除pc所在的那个店的 { pc--; b[0]--; } else { b[++pc]=i++;//最后的栈的后面多了一个0是为了下面进行的操作的 b[0]++; } } n=pc-1;//1到pc的结果的 b[0]=b[pc-1];//为了循环的 // for(i=0; i<=n+1; i++) // printf("%d\n",b[i]); } double dis(point p1,point p2) { double s=(double)((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); s=sqrt(s); return s; } double degree(point p1,point p2,point p3,point p4) { double s=(double)((p2.x-p1.x)*(p4.x-p3.x)+(p2.y-p1.y)*(p4.y-p3.y)); double t=dis(p1,p2)*dis(p3,p4); return acos(s/t);//算出来的是角度 } void len() { double Max=0; int i; for(i=1; i<=n; i++) Max+=sqrt((double)((a[b[i]].x-a[b[i+1]].x)*(a[b[i]].x-a[b[i+1]].x)+(a[b[i]].y-a[b[i+1]].y)*(a[b[i]].y-a[b[i+1]].y)));//求一部分的边长的 for(i=1; i<=n; i++) { double m=degree(a[b[i]],a[b[i-1]],a[b[i]],a[b[i+1]]); m=pi-m;//对角的 Max+=l*m; } printf("%d\n",(int)(Max+0.5)); } int main() { int i,j,x,y; while(scanf("%d%d",&n,&l)!=EOF) { x=INT_MAX; y=INT_MAX; for(i=0; i<n; i++) { scanf("%d%d",&a[i].x,&a[i].y); if(a[i].y<y) { y=a[i].y;j=i;x=a[i].x; } else if(a[i].y==y && a[i].x<x) { y=a[i].y;j=i;x=a[i].x; } } a[j].x=a[0].x;a[j].y=a[0].y; a[0].x=x;a[0].y=y; p=&a[0]; qsort(&a[1],n-1,sizeof(point),cmp); // for(i=0; i<n; i++) // printf("%d %d %d\n",i,a[i].x,a[i].y); foud(); len();//计算需要的篱笆的长度 } return 0; }
相关文章推荐
- Poj 1113 Wall (凸包Graham)
- POJ 1113 Wall 凸包求周长
- POJ 1113 Wall(计算几何--凸包的周长)
- poj 1113 Wall 凸包的应用
- POJ 1113 WALL (凸包问题)
- Wall(凸包POJ 1113)
- POJ 1113 Wall(凸包)
- poj 1113 Wall-----凸包
- POJ 1113 || HDU 1348: wall(凸包问题)
- POJ 1113 Wall (计算几何-凸包)
- POJ 1113 Wall (凸包)
- poj 1113 wall 简单的凸包
- POJ 1113 凸包2 Graham-scan 入门题(极角序,水平序)
- POJ1113:Wall(凸包)
- POJ 1113(计算几何初步——凸包加圆周长)
- poj 1113 Wall (凸包)
- poj 1113 凸包模板
- POJ 1113 WALL(凸包-计算几何)
- POJ 1113 凸包
- POJ 1113 Wall 二维凸包