POJ - 1113 Wall (凸包模板题)

原题链接

模板题,直接说思路。

思路:

要求一距离凸包为 L 的图形的周长,即为 凸包周长+L为半径的圆周长 ,直接用 Graham 求一次凸包即可。

  1 /*
  2 * @Author: windystreet
  3 * @Date:   2018-08-02 20:41:25
  4 * @Last Modified by:   windystreet
  5 * @Last Modified time: 2018-08-02 22:30:59
  6 */
  7 #include <stdio.h>
  8 #include <math.h>
  9 #include <string.h>
 10 #include <algorithm>
 11 using namespace std;
 12
 13 #define X first
 14 #define Y second
 15 #define eps  1e-2
 16 #define gcd __gcd
 17 #define pb push_back
 18 #define PI acos(-1.0)
 19 #define lowbit(x) (x)&(-x)
 20 #define bug printf("!!!!!\n");
 21 #define mem(x,y) memset(x,y,sizeof(x))
 22
 23 typedef long long LL;
 24 typedef long double LD;
 25 typedef pair<int,int> pii;
 26 typedef unsigned long long uLL;
 27
 28 const int maxn = 1e3+2;
 29 const int INF  = 1<<30;
 30 const int mod  = 1e9+7;
 31
 32 struct point
 33 {
 34     int x,y;
 35     point (){}
 36     point(int _x,int _y){
 37         x = _x;y = _y;
 38     }
 39     point operator - (const point &b)const{                  // 定义减法
 40         return point(x-b.x,y-b.y);
 41     }
 42     int operator ^ (const point &b)const{                    // 定义叉积
 43         return x*b.y - y*b.x;
 44     }
 45 };
 46 point List[maxn];
 47 int Stack[maxn],top;
 48
 49 double dis(point p1,point p2){
 50     return sqrt((double)((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)));
 51 }
 52 bool cmp(point p1,point p2){                                // 极角排序
 53     int tmp = (p1-List[0])^(p2-List[0]);
 54     if(tmp>0)return true;
 55     else if(tmp==0 && (dis(List[0],p1)<dis(List[0],p2))) return true;
 56     else return false;
 57 }
 58 void Graham(int n){
 59     point p0;
 60     int k = 0;
 61     p0 = List[0];
 62     for(int i=1;i<n;i++){
 63         if((p0.y > List[i].y)||(p0.y == List[i].y && p0.x > List[i].x)){
 64             p0 = List[i]; k = i;
 65         }
 66     }
 67     swap(List[k],List[0]);
 68     sort(List+1,List+n,cmp);
 69     if(n==1){
 70         top = 0;Stack[0] = 0; return ;
 71     }else if(n==2){
 72         top = 1;Stack[0] = 0;Stack[1] = 1;return;
 73     }
 74     Stack[0] = 0;Stack[1] = 1;top = 1;
 75     for(int i = 2 ;i < n; i++){
 76         while(top > 0 && ((List[Stack[top]]-List[Stack[top-1]])^(List[i]-List[Stack[top-1]]))<=0)top--;
 77         Stack[++top] = i;
 78
 79     }
 80 }
 81
 82 void solve(){
 83     int n,L;
 84     while(~scanf("%d%d",&n,&L)){
 85         double ans = 0;
 86         for(int i=0;i<n;i++){
 87             scanf("%d%d",&List[i].x,&List[i].y);
 88         }
 89         Graham(n);
 90         for(int i=0;i<top;i++){
 91             ans += dis(List[Stack[i]],List[Stack[i+1]]);
 92         }
 93         ans += dis(List[Stack[0]],List[Stack[top]]);            // 计算凸包周长
 94         ans += PI*L*2.0;                                        // 加上一个圆的周长
 95         printf("%d\n",(int)(ans+0.5));                            // 答案四舍五入
 96     }
 97     return;
 98 }
 99
100 int main()
101 {
102 //    freopen("in.txt","r",stdin);
103 //    freopen("out.txt","w",stdout);
104 //    ios::sync_with_stdio(false);
105     int t = 1;
106     while(t--){
107     //    printf("Case %d: ",cas++);
108         solve();
109     }
110     return 0;
111 }

原文地址:https://www.cnblogs.com/windystreet/p/9410736.html

时间: 2024-08-28 11:39:03

POJ - 1113 Wall (凸包模板题)的相关文章

poj 1113 Wall (凸包模板题)

Wall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 32808   Accepted: 11137 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 w

POJ 1113 - Wall 凸包模板

此题为凸包问题模板题,题目中所给点均为整点,考虑到数据范围问题求norm()时先转换成double了,把norm()那句改成<vector>压栈即可求得凸包. 初次提交被坑得很惨,在GDB中可以完美运行A掉,到OJ上就频频RE(此处应有黑人问号) 后来发现了问题,原因是玩杂耍写了这样的代码 struct point { int x, y; point (){ scanf("%d%d", &x, &y); } ... }pt[MAXN]; 于是乎,在swap

POJ 1113 Wall (凸包)

题目地址:POJ 1113 先求出凸包的周长,然后剩下的弧合起来一定是个半径为l的圆,然后再加上以l为半径的圆的周长即可. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <

poj 1113 Wall 凸包的应用

题目链接:poj 1113   单调链凸包小结 题解:本题用到的依然是凸包来求,最短的周长,只是多加了一个圆的长度而已,套用模板,就能搞定: AC代码: 1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cmath> 5 using namespace std; 6 int m,n; 7 struct p 8 { 9 double x,y; 10 friend i

POJ 1113 Wall 凸包 裸

LINK 题意:给出一个简单几何,问与其边距离长为L的几何图形的周长. 思路:求一个几何图形的最小外接几何,就是求凸包,距离为L相当于再多增加上一个圆的周长(因为只有四个角).看了黑书使用graham算法极角序求凸包会有点小问题,最好用水平序比较好.或者用Melkman算法 /** @Date : 2017-07-13 14:17:05 * @FileName: POJ 1113 极角序求凸包 基础凸包.cpp * @Platform: Windows * @Author : Lweleth (

POJ 1113 Wall (凸包 + 思维)

题目:传送门 题意:有一个 n 多边形城堡,先需在城堡外建围墙,使得围墙到城堡的距离不得小于 L,且围墙的周长最小. 思路:答案就是凸包周长 + 半径为 L 的圆的周长.   证明 A.B.C.D四个点,每个点都有 360 度, 然后,角1.2.3.4构成多变形的内角和为 360度,然后每个点,又要减去两个90度,那么剩下的就是圆心角5.6.7.8,它们的和为 4 * (360 - 180) - 360 = 360,刚好是一个圆.推广到任意多边形也是类似的. #include <iostream

POJ 1113 凸包模板题

上模板. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <vector> #include <utility> #include <stack> #include <queue> #include <map> #include

POJ 3528 hdu 3662 三维凸包模板题

POJ 3528题:http://poj.org/problem?id=3528 HDU 3662:http://acm.hdu.edu.cn/showproblem.php?pid=3662 一个是求三维凸包面数,一个是求三维凸包表面积,都是很裸的. 贴代码: #include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> #include<stdlib.h>

G++和C++ &amp;&amp; POJ 1113 Wall

PS: 次题目虽然叙述点的个数大于等于3但是并不保证凸包是否存在,所以还要判断一下.经常刷题的孩纸可能会遇到用C++ 可用AC的题目用G++ 却 Wrong Answer. 思考过为什么吗? 对于double 类型用%lf 输入用%lf输出是window 环境下VC的标准但不是真正的标准,对于double 类型 真正的标准是用%lf输入,用%f输出.所以把%.0lf改为%.0f 在G++环境下面就可用轻松AC了. 还有%lld 和 %I64d, 同时也学习一下控制精度的技巧,比如 printf(