链接:传送门

题意:给出二维坐标轴上 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;
}

转载于:https://www.cnblogs.com/WArobot/p/6822125.html

HDU 1348 Wall ( 凸包周长 )相关推荐

  1. 二维凸包(模板) hdu 1348 求凸包的周长

    题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1348 凸包模板: const int N =1010; const double PI = 3.141 ...

  2. POJ - Wall(凸包周长)

    题目链接:http://poj.org/problem?id=1113 Time Limit: 1000MS Memory Limit: 10000K Description Once upon a ...

  3. hdu 1348 wall

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

  4. [codevs 1298] 凸包周长 [codevs 3201] 奶牛代理商 XI

    题解: 今天开始学习计算几何. 这是一道计算几何求凸包周长的模板题,采用Andrew算法. 第二道题改下输出即可. 最后凸包周长的求法注意第一个点和最后一个点是同一个. 代码 100ms 3MB #i ...

  5. HDU 5928 DP 凸包graham

    给出点集,和不大于L长的绳子,问能包裹住的最多点数. 考虑每个点都作为左下角的起点跑一遍极角序求凸包,求的过程中用DP记录当前以j为当前末端为结束的的最小长度,其中一维作为背包的是凸包内侧点的数量.也 ...

  6. HDU 1348(Wall)

    计算所有点的凸包,然后凸包的每条边向外平移 L,相邻边用弧填充,所有弧合起来恰好是一个圆.所以最终的长度为凸包所有边的长度加上圆的周长. #include <cstdio> #includ ...

  7. [WIKIOI1298]凸包周长[裸凸包]

    http://www.wikioi.com/problem/1298/ 这是题目. 是一道裸的凸包算法题,但是我一开始还是写WA了.先贴代码 1 #include <cstdio> 2 # ...

  8. poj 1113 Wall 凸包的应用

    题目链接:poj 1113   单调链凸包小结 题解:本题用到的依然是凸包来求,最短的周长,只是多加了一个圆的长度而已,套用模板,就能搞定: AC代码: 1 #include<iostream& ...

  9. poj 1873 The Fortified Forest (位运算枚举 + 凸包周长)

    题目链接:http://poj.org/problem?id=1873 大意:有一片N棵树的森林,要从中砍掉几棵树做成篱笆,把剩下的树围起来 输入:给N课树,每棵树的坐标是x,y,每棵树有一个vi和l ...

最新文章

  1. 信号中断 与 慢系统调用
  2. 计算机会计和传统手工会计的区别,手工会计与计算机会计之间的区别.doc
  3. 零侵入性:一个注解,优雅的实现循环重试功能
  4. WinAPI-命令规则
  5. 漫画:如何给女朋友解释什么是“锟斤拷”?
  6. 系统分析员备考之系统工程篇(系统工程基础)
  7. flink API之 Environment
  8. php实现观看记录,PHP实现浏览历史记录
  9. fx5u模拟量如何读取_最全三菱FX5U系列PLC视频
  10. mysql 中间表的好处_MySql 使用中间表来提高统计查询速度
  11. java混淆加密_源代码部分加密混淆方案
  12. android 自定义键盘长按事件,Android触发事件总结(触摸屏事件,手势识别,键盘事件,模拟鼠标/按键事件)...
  13. 34个有用的 JavaScript 库,现在就可以用起来
  14. Win11系统怎么获得管理员权限
  15. 小米商城首页仿写+课程总结报告
  16. 前端知识:使用layui模板搭建页面,简单快捷
  17. Hbuider H5+App获取手机状态栏高度
  18. 苹果股价盘后涨超5% 市值一度突破万亿
  19. StringBuffer(史上最详细)
  20. matlab里面的sul,MATLAB语言在电机控制系统仿真研究中的应用

热门文章

  1. POJ 2828Buy Tickets
  2. MFC用PostMessage传递消息
  3. 大数据_Flink_流式处理_简介_为什么要用Flink---Flink工作笔记0002
  4. 基于Spring Security的认证方式_Spring Security 的结构总览_Spring Security OAuth2.0认证授权---springcloud工作笔记122
  5. SpringCloud工作笔记081---SpringCloud Hystrix Turbine(断路器聚合监控)的基本使用
  6. 项目思考001---近期这个电台购物项目的一点点思考
  7. SpringCloud学习笔记025---SpringBoot_注释理解_@Qualifier 注释
  8. PHP错误提示的关闭方法详解
  9. shell读取文件的每一行
  10. php 解压zip到目录下,php 解压zip压缩包内容到指定目录的实例