POJ1113浅析——Wall ——凸包
来源:互联网 发布:3d max螺丝数据 编辑:程序博客网 时间:2024/04/30 06:24
题目大意:
要在一座城堡周围建围墙,要求用料最省。围墙距城堡不得小于 距离 L。
浅析:
题目要求用料最省,求围墙长度。因此只要找一个最小的多边形能够围住城堡即可。因此是一个求凸包周长的问题。
距离不得小于L。因此凸包顶点会形成扇形。各扇形聚在一起形成了一个圆。
所以所求周长 = 凸包周长 + 一个圆的周长。
因为这个题数据量不大,graham中的极角排序我还不会,所以用了卷包裹的方法来求凸包。
卷包裹法最后得到的点并不一定是凸包顶点,所以每确定一个点,一定要判断一下是不是终点。(即判断它的后继点是否在凸包起点的左侧,如果是,那这个点就是凸包终点,与起点连载一起形成凸包)。
卷包裹过程中依次更新周长sum值。然后加上起点终点的长度,再加上圆的周长,就得到了所求值。
我的代码如下:(供参考)
#include<stdio.h>#include<math.h>#include<stdlib.h>#include<math.h>#define Pi 3.1415926535898#define inf 10001struct Point{ int x, y; int mark; }a[1010];int left(int minp, int num, int i){ return (a[num].x-a[minp].x)*(a[i].y-a[minp].y)-(a[i].x-a[minp].x)*(a[num].y-a[minp].y); }double dis(int minp, int num, int i){ return sqrt( (a[i].x-a[minp].x)*(a[i].x-a[minp].x)+(a[i].y-a[minp].y)*(a[i].y-a[minp].y) ) - sqrt( (a[num].x-a[minp].x)*(a[num].x-a[minp].x)+(a[num].y-a[minp].y)*(a[num].y-a[minp].y) ); }double dist(int minp, int num){ return sqrt( (a[num].x-a[minp].x)*(a[num].x-a[minp].x)+(a[num].y-a[minp].y)*(a[num].y-a[minp].y) ); }int min(int m, int n){ if(m<n) return m; return n;}int max(int m, int n){ if(m>n) return m; return n; }int online(int minp, int num, int tmp){ if( a[num].x >= min(a[minp].x, a[tmp].x) && a[num].x<=max(a[minp].x, a[tmp].x) ) return 1; return 0; }int main(){ int i, n, l, minx=inf, miny=inf, minp, time, num, tmp; double sum=0.0; scanf("%d%d", &n, &l); for(i=0; i<n; i++) { scanf("%d%d", &a[i].x, &a[i].y); a[i].mark = 1; if(a[i].y<miny || (a[i].y==miny && a[i].x<minx) ) { miny = a[i].y; minx = a[i].x; minp = i; } } tmp = minp; a[minp].mark = 0; time = 0; while(time!=n-1) { //卷包裹法求下一个凸包顶点 for(i=0; i<n; i++) { if(a[i].mark) { num=i; break; } } for(i=0; i<n; i++) { if(a[i].mark && i!=num && (left(minp, num, i)<0||(left(minp, num, i)==0&&dis(minp, num, i)<0))) { num=i; } } //判断 minp点是不是凸包终点,如果是,则与其连接的点为起点 if(minp!=tmp && (left(minp, num, tmp) < 0 || (left(minp, num, tmp)==0 && online(minp, num, tmp) ) ) ) { num=tmp; break; } sum = sum + dist(minp, num); minp = num; a[num].mark = 0; //标记为凸包顶点 time++; //最坏情况下循环次数time = n-1 } //printf("sum=%lf\n", sum); sum += (Pi * l * 2 + dist(minp, tmp)); //凸包周长(+起点和终点的距离)+一个圆周长 printf("%.0f\n", sum); //system("pause"); return 0; }
- POJ1113浅析——Wall ——凸包
- POJ1113——Wall(凸包)
- poj1113——Wall(凸包)
- POJ1113——WALL 凸包
- poj1113——Wall
- poj1113——Wall(计算几何凸包)
- POJ1113 Wall 凸包
- poj1113--Wall(凸包)
- poj1113 Wall 凸包
- poj1113 Wall --凸包
- poj1113 Wall【凸包】
- poj1113 Wall 凸包
- 【凸包_Graham】Wall POJ1113
- POJ1113 wall 简单凸包
- kyeremal-poj1113-Wall-凸包
- [POJ1113]Wall(凸包)
- POJ1113:Wall(凸包)
- ACM-计算几何之Wall——poj1113
- 基于NLB的 RMS部署!
- C8051F与80C51系列单片机的初始化比较
- Tomcat内存溢出的原因
- 如何使用自己的makefile编译android ndk项目
- SDCC讲师预热专访:淘宝岑文初谈开放平台架构
- POJ1113浅析——Wall ——凸包
- nandflash裸机驱动程序的分析
- sprintf函数的用法(各种类型转换为char*)
- servlet过滤器和监听器
- Ubuntu 12.04 iBus输入法托盘图标无故消失解决办法
- ios 判断当前的设备是那一种型号
- uva 10012 - How Big Is It?
- zoj1205-----------Martian Addition 大数处理
- 算法的封装与切换——策略模式(三)