Wall
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 41143   Accepted: 14068

Description

Once upon a time there was a greedy King who ordered his chief Architect to build a wall around the King's castle. The King was so greedy, that he would not listen to his Architect's proposals to build a beautiful brick wall with a perfect shape and nice tall towers. Instead, he ordered to build the wall around the whole castle using the least amount of stone and labor, but demanded that the wall should not come closer to the castle than a certain distance. If the King finds that the Architect has used more resources to build the wall than it was absolutely necessary to satisfy those requirements, then the Architect will loose his head. Moreover, he demanded Architect to introduce at once a plan of the wall listing the exact amount of resources that are needed to build the wall. 

Your task is to help poor Architect to save his head, by writing a program that will find the minimum possible length of the wall that he could build around the castle to satisfy King's requirements.

The task is somewhat simplified by the fact, that the King's castle has a polygonal shape and is situated on a flat ground. The Architect has already established a Cartesian coordinate system and has precisely measured the coordinates of all castle's vertices in feet.

Input

The first line of the input file contains two integer numbers N and L separated by a space. N (3 <= N <= 1000) is the number of vertices in the King's castle, and L (1 <= L <= 1000) is the minimal number of feet that King allows for the wall to come close to the castle.

Next N lines describe coordinates of castle's vertices in a clockwise order. Each line contains two integer numbers Xi and Yi separated by a space (-10000 <= Xi, Yi <= 10000) that represent the coordinates of ith vertex. All vertices are different and the sides of the castle do not intersect anywhere except for vertices.

Output

Write to the output file the single number that represents the minimal possible length of the wall in feet that could be built around the castle to satisfy King's requirements. You must present the integer number of feet to the King, because the floating numbers are not invented yet. However, you must round the result in such a way, that it is accurate to 8 inches (1 foot is equal to 12 inches), since the King will not tolerate larger error in the estimates.

Sample Input

9 100
200 400
300 400
300 300
400 300
400 400
500 400
500 200
350 200
200 200

Sample Output

1628

Hint

结果四舍五入就可以了

Source

 
思路:就是用所有点构成的凸包,然后将凸包向外推L米就可以了,可以知道将墙直接外推L米,墙的长度没变,但是两堵墙之间会有缝隙,这个如果用直线相连
就会浪费,所以直接用圆弧相连,半径为L,所以:总长度 = 原凸包周长 + 所有圆弧的长度。其实所有圆弧的长度之和会构成一个半径为L的圆,所以最后的结果: 总长度 = 原凸包周长 + 圆的周长(R=L)。关于为什么所有圆弧会拼成一个原,我一也是看了许多博客慢慢理解的,证明如下:
 

证明:

先从简单的例子看起:假设现在的凸包有四个顶点构成,可以就一个顶点来观察,我们可以看到此处的周角由四个部分组成:2个直角,一个凸包内角,一个圆弧对应的圆心角。

同理每个顶点都有类似的关系,同时周角固定为360度,而凸包内角和为(4-2)*180 ;

所以总的圆弧对应的圆心角 = 4个周角 - 4 * 2个直角 - 4个凸包内角 = 4 * 360 - 4 * 2 * 90 - (4-2)*180 = 1440-720-360 =360度。

现在推广到n个顶点的凸包:

则所有内角和  =  周角 * n - n * 2个直角 - (n-2)*180 = 360*n - n *180 - n*180 + 360 = 360度。

故对于任意的凸包,所有的圆弧对应的圆心角之和都为360度,它们构成一个完整的圆。

ac代码如下:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define N 10005
const double PI = acos(-1.0); int n,tot;//n为二维平面上点的个数,tot为凸包上点的个数
struct node {
int x,y;
}a[N],p[N]; //p[]用来储存凸包 double dis(node a1,node b1){ //两点间距离公式
return sqrt((a1.x-b1.x)*(a1.x-b1.x)+(a1.y-b1.y)*(a1.y-b1.y) + 0.00);
} //叉积:返回结果为正说明p2在向量p0p1的左边(三点构成逆时针方向);
//为负则相反;为0则三点共线(叉积的性质很重要)
double multi(node p0,node p1,node p2){ //
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
} //极角排序:极角排序是根据坐标系内每一个点与x轴所成的角,逆时针比较。按照角度从小到大的方式排序
int cmp(node p1,node p2){ //极角排序;
int x=multi(p1,p2,a[0]);
if(x>0||(x==0&&dis(p1,a[0])<dis(p2,a[0])))
return 1;
return 0;
} void Graham(){ //求凸包
int k=0;
for(int i=0;i<n;i++) //找到最下最左的一个点
if(a[i].y<a[k].y||(a[i].y==a[k].y&&a[i].x<a[k].x))
k=i;
swap(a[0],a[k]); //将其设置为第一个点
sort(a+1,a+n,cmp);
tot=2,p[0]=a[0],p[1]=a[1]; //p[]模拟栈,用来储存凸包
for(int i=2;i<n;i++){
while(tot>1&&multi(p[tot-1],p[tot-2],a[i])>=0)
tot--; //右拐就回退
p[tot++]=a[i]; //左拐就放入
}
} double getArea(){
struct node b[3];
b[0] = p[0], b[1] = p[1], b[2] = p[2];
double area = 0;
for(int i = 2; i < tot; i++){
area += multi(b[0], b[1], p[i]) / 2.0;
b[1] = p[i];
}
return area;
} double getGirth(){
double rt = 0;
for(int i = 0; i < tot; i++){
rt += dis(p[i], p[(i+1)%tot]);
}
return rt;
} int main(){
double L;
while(cin >> n >> L){
tot = 0;
for(int i = 0; i < n; i++){
cin >> a[i].x >> a[i].y;
}
Graham();
double res = getGirth();
res += 2*PI*L;
cout << int(res + 0.5) << endl;
}
return 0;
}

  

81-POJ-Wall(计算几何)的更多相关文章

  1. POJ 1113 Wall(计算几何の凸包)

    Description Once upon a time there was a greedy King who ordered his chief Architect to build a wall ...

  2. POJ 1556 计算几何+最短路

    代码1: #include<iostream> #include<stdio.h> #include<string> #include<string.h> ...

  3. POJ 2954-Triangle(计算几何+皮克定理)

    职务地址:POJ 2954 意甲冠军:三个顶点的三角形,给出,内部需求格点数. 思考:就像POJ 1265. #include <stdio.h> #include <math.h& ...

  4. poj 1410 计算几何

    /** 注意: 千万得小心..就因为一个分号,调了一个晚上... **/ #include <iostream> #include <algorithm> using name ...

  5. poj 2653 计算几何

    #include <iostream> #include <cstring> #include <algorithm> #include <cmath> ...

  6. poj 1269 计算几何

    /** 判断直线位置关系 **/ #include <iostream> #include <cmath> #include <cstdio> using name ...

  7. poj 3304 计算几何

    大意: 是否存在一条直线,使所有线段在直线上的投影至少交与一点 思路: 转换为是否存在一条直线与所有的线段相交,做这条直线的垂线,那么垂线即为所求 **/ #include <iostream& ...

  8. poj 2398 计算几何

    #include <iostream> #include<cstdio> #include<cstring> #include <algorithm> ...

  9. BZOJ 1113 Wall ——计算几何

    凸包第一题. 自己认为自己写的是Andrew 其实就是xjb写出来居然过掉了测试. 刚开始把pi定义成了int,调了半天 #include <map> #include <cmath ...

  10. POJ 3855 计算几何·多边形重心

    思路: 多边形面积->任选一个点,把多边形拆成三角,叉积一下 三角形重心->(x1+x2+x3)/3,(y1+y2+y3)/3 多边形重心公式题目中有,套一下就好了 计算多边形重心方法: ...

随机推荐

  1. dd装机

    如何在 Linux 系统中使用 dd 命令而不会损毁你的磁盘 使用 Linux 中的 dd 工具安全.可靠地制作一个驱动器.分区和文件系统的完整镜像. _这篇文章节选自 Manning 出版社出版的图 ...

  2. mysql存储引擎之innodb学习

    innodb引擎特点1.支持事务:支持4个事务隔离级别,支持多版本读. 2.行级锁定(更新时一般是锁定当前行):通过索引实现,全表扫描仍然会是表锁,注意间隙 锁的影响 3.读写阻塞与事务隔离级别有关 ...

  3. 搭建基于hyperledger fabric的联盟社区(九) --检索状态数据库

    一.启动elasticsearch服务 官网下载压缩包解压,进入bin目录启动: ./elasticsearch 通过ip访问 localhost:9200,可以看到如下信息 { name: &quo ...

  4. JVM内存管理之GC简介

    为何要了解GC策略与原理?        原因在上一章其实已经有所触及,就是因为在平时的工作和研究当中,不可避免的会遇到内存溢出与内存泄露的问题.如果对GC策略与原理不了解的情况下碰到了前面所说的问题 ...

  5. 黄聪:使用Add-on SDK开发火狐扩展

    2014年3月7号更新:火狐已经关闭Add-on SDK服务啦!我也转用360急速浏览器来开发浏览器插件了. 如果精通JS.HTML.CSS开发的朋友,直接看这个教程估计就能懂了 ---------- ...

  6. .NET实现多个不同有效时间Session方案思考

    什么是Session?简单讲,Session是一种服务端用于保存每个客户端用户的状态信息的机制.客户端第一次访问时,服务端从分配一个空间专门存储该客户端的信息,后续访问时便可以直接获取或者更新状态信息 ...

  7. mysql实战优化之一:sql优化

    1.选取最适用的字段属性 MySQL 可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快.因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得 ...

  8. CentOS6.4 上搭建NIS网络信息服务器

    NIS(Network Information Service)网络信息服务,主要功能是提供用户登录信息给客户端主机查询之用,用于企业局域网Linux主机账户的集中管理(非跨平台).NIS服务器在大型 ...

  9. Maven的学习

    Maven是Apache的一个项目,它使用对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具.它集项目的构建,清理,编译等于一体,以前我们在使用IDE时,基本上一 ...

  10. Nginx 服务器开启status页面检测服务状态

    一.Nginx status monitor 和apache 中服务器状态一样.输出的内容如:  第1列: 当前与http建立的连接数,包括等待的客户端连接:2 第2列: 接受的客户端连接总数目:20 ...