**链接:****传送门 **

题意:给出二维坐标轴上 n 个点,这 n 个点构成了一个城堡,国王想建一堵墙,城墙与城堡之间的距离总不小于一个数 L ,求城墙的最小长度,答案四舍五入

思路:城墙与城堡直线长度是相等的,当城堡出现拐角时,城墙必然会出现一段圆弧,这些圆弧最终会构成一个半径为 L 的圆,所以答案就是凸包的周长 + 圆的周长

balabala:

  1. 采用Jarvis步进法来求凸包,Jarvis步进法复杂度为O(nh),h为凸包顶点个数
  2. 采用Graham-Scan来求凸包,Graham - Scan 法复杂度为O(nlogn)

如有错误请一定指出!


Graham - Scan法:

/*************************************************************************
> File Name: hdu1348t2.cpp
> Author: WArobot
> Blog: http://www.cnblogs.com/WArobot/
> Created Time: 2017年05月07日 星期日 20时49分15秒
************************************************************************/ #include<bits/stdc++.h>
using namespace std; // Graham - Scan
// O(nlgn) #define PI 3.1415926535
const int maxn = 1010;
struct point{
double x,y;
}; bool cmp(point a,point b){
return (a.y<b.y || (a.y==b.y && a.x<b.x));
}
bool mult(point sp,point ep,point op){
return (sp.x-op.x)*(ep.y-op.y)>=(sp.y-op.y)*(ep.x-op.x);
}
point res[maxn];
int Graham(point pnt[],int n){
int i , len , k = 0 , top = 1;
sort(pnt,pnt+n,cmp);
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(int 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;
}
double point_dis(point a,point b){
return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
int main(){
int T , n , L , kase = 0;
point pi[maxn];
scanf("%d",&T);
while(T--){
if(kase > 0) printf("\n");
kase++;
scanf("%d%d",&n,&L);
for(int i=0;i<n;i++) scanf("%lf%lf",&pi[i].x,&pi[i].y);
int t = Graham(pi,n);
double ans = 2*PI*L;
for(int i=0;i<t;i++){
ans += point_dis( res[i] , res[ (i+1)%t ] );
}
printf("%.lf\n",ans);
}
return 0;
}

Jarvis步进法:

/*************************************************************************
> File Name: hdu1348.cpp
> Author: WArobot
> Blog: http://www.cnblogs.com/WArobot/
> Created Time: 2017年05月07日 星期日 18时55分57秒
************************************************************************/ #include<bits/stdc++.h>
using namespace std; #define PI 3.1415926535
const int maxn = 1010;
struct point{
double x,y;
}pi[maxn]; bool cmp(point a,point b){
return ( a.y<b.y || a.y==b.y && a.x<b.x);
} int n,L,ans[maxn],cnt,sta[maxn],tail;
// 检查是否严格左转,共线不算左转
bool CrossLeft(point p1,point p2,point p3){
return ((p3.x-p1.x)*(p2.y-p1.y) - (p2.x-p1.x)*(p3.y-p1.y)) < 0;
}
void Jarvis(){
tail = cnt = 0;
sort(pi,pi+n,cmp);
sta[tail++] = 0; sta[tail++] = 1;
for(int i=2;i<n;i++){
while(tail>1 && !CrossLeft( pi[ sta[tail-1] ] , pi[ sta[tail-2] ] , pi[i] ))
tail--;
sta[ tail++ ] = i;
}
for(int i=0;i<tail;i++) ans[cnt++] = sta[i];
tail = 0; sta[ tail++ ] = n-1; sta[ tail++ ] = n-2;
for(int i=n-3;i>=0;i--){
while(tail>1 && !CrossLeft( pi[ sta[tail-1] ] , pi[ sta[tail-2] ] , pi[i] ))
tail--;
sta[ tail++ ] = i;
}
for(int i=0;i<tail;i++) ans[cnt++] = sta[i];
}
double Point_dis(point a,point b){
return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
int main(){
int T , kase = 0;
scanf("%d",&T);
while(T--){
if(kase) printf("\n");
kase++;
scanf("%d%d",&n,&L);
for(int i=0;i<n;i++) scanf("%lf%lf",&pi[i].x,&pi[i].y);
Jarvis();
double re = 2*PI*L;
for(int i=0;i<cnt-1;i++){
re += Point_dis( pi[ans[i]] , pi[ans[i+1]] );
}
printf("%.0lf\n",re);
}
return 0;
}

HDU 1348 Wall ( 凸包周长 )的更多相关文章

  1. hdu 1348 Wall (凸包模板)

    /* 题意: 求得n个点的凸包.然后求与凸包相距l的外圈的周长. 答案为n点的凸包周长加上半径为L的圆的周长 */ # include <stdio.h> # include <ma ...

  2. hdu 1348 Wall (凸包)

    Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  3. hdu 1348:Wall(计算几何,求凸包周长)

    Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  4. hdu 1348 (凸包求周长)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 Wall Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  5. hdu 1348 Wall(凸包模板题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 Wall Time Limit: 2000/1000 MS (Java/Others)    M ...

  6. HDU 1348 Wall 【凸包】

    <题目链接> 题目大意: 给出二维坐标轴上 n 个点,这 n 个点构成了一个城堡,国王想建一堵墙,城墙与城堡之间的距离总不小于一个数 L ,求城墙的最小长度,答案四舍五入. 解题分析: 求 ...

  7. HDU 1348 Wall

    题解:计算凸包周长 #include <iostream> #include <cmath> #include <algorithm> const int size ...

  8. POJ 1113 || HDU 1348: wall(凸包问题)

    传送门: POJ:点击打开链接 HDU:点击打开链接 以下是POJ上的题: Wall Time Limit: 1000MS   Memory Limit: 10000K Total Submissio ...

  9. hdu 1348【凸包模板】

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

随机推荐

  1. 用SufaceGO加微软全家桶做个遥控车(一)

    作为一个dotnet技术的新手我是不好意思写帖子的,原因就是本人技术太水了,写出的帖子肯定会让人笑话.所以这次我是厚着脸皮写出这个帖子的,希望大佬们轻喷了.我的目标就是用SurfaceGo实现一个和我 ...

  2. [poj 3666] Making the Grade (离散化 线性dp)

    今天的第一题(/ω\)! Description A straight dirt road connects two fields on FJ's farm, but it changes eleva ...

  3. Python 绘制2016世界GDP地图

    2016世界GDP地图 从https://datahub.io/core/gdp#data下载得到json文件. # country_code.py 获取国家二字代码 # 从pygal.maps.wo ...

  4. 【hiho一下 第十一周】树中的最长路

    [题目链接]:http://hihocoder.com/problemset/problem/1050 [题意] [题解] 有一个经典的求树的直径的方法; 首先; 树的直径的两端的端点必然都在树的叶子 ...

  5. Elasticsearch 三种分页方式

    from + size 浅分页 "浅"分页可以理解为简单意义上的分页.它的原理很简单,就是查询前20条数据,然后截断前10条,只返回10-20的数据.这样其实白白浪费了前10条的查 ...

  6. inconsistent line endings 解决方法

     I'm using Unity 3D in combination with Visual Studio 2008 on a Windows 7 64 bit system. When savi ...

  7. 0x28 IDA*

    一个早上做完了我真牛B 就是A*用于DFS啊,现在我才发现迭代加深真是个好东西. poj3460 %了%了我们的目标是把它的顺序变对,那么第i个位置的值+1是要等于第i+1个位置的值的.对于一个操作, ...

  8. bzoj5288: [Hnoi2018]游戏

    我还是太年轻了... 考场上就是直接枚举预处理当前位置左右延伸到的最远距离,好像是水了20.. 然后噶爷爷居然随机一下就AC了????mengbier #include<cstdio> # ...

  9. 杂项:ExtJS

    ylbtech-杂项:ExtJS extjs是一种软件.自动生成行号,支持checkbox全选,动态选择显示哪些列,支持本地以及远程分页,可以对单元格按照自己的想法进行渲染,这些也算可以想到的功能. ...

  10. 给centos重新安装yum的base-repo源

    转自:https://blog.csdn.net/lovemysea/article/details/79552952 如果自己的centos的系统yum源出现问题了,如何才能修复? 方式一:使用国内 ...