POJ 1113 Wall(思维 计算几何 数学)

题意

题目链接

给出平面上n个点的坐标。你需要建一个围墙,把所有的点围在里面,且围墙距所有点的距离不小于l。求围墙的最小长度。
\(n \leqslant 10^5\)

Sol

首先考虑如果没有l的限制,那么显然就是凸包的长度。

现在了距离的限制,那么显然原来建在凸包上的围墙要向外移动\(l\)的距离,同时会增加一些没有围住的位置

因为多边形的外交和为360,再根据补角的性质,画一画图就知道这一块是一个半径为\(l\)的圆。

因为总答案为凸包周长 + \(2 \pi l\)

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN = 1e5 + 10;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int N, top;
struct Point {
    double x, y;
    Point operator - (const Point &rhs) const {
        return {x - rhs.x, y - rhs.y};
    }
    Point operator + (const Point &rhs) const {
        return {x + rhs.x, y + rhs.y};
    }
    double operator ^ (const Point &rhs) const {
        return x * rhs.y - y * rhs.x;
    }
    bool operator < (const Point &rhs) const {
        return x == rhs.x ? y < rhs.y : x < rhs.x;
    }
}p[MAXN], q[MAXN];
template<typename A> A sqr(A x) {
    return x * x;
}
double dis(Point a, Point b) {
    return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));
}
void insert(Point now) {
    while(top > 1 && ((q[top] - q[top - 1]) ^ (now - q[top - 1])) < 0) top--;
    q[++top] = now;
}
int main() {
    N = read(); double L = read();
    for(int i = 1; i <= N; i++) p[i].x = read(), p[i].y = read();
    sort(p + 1, p + N + 1);
    q[top = 1] = p[1];
    for(int i = 2; i <= N; i++) insert(p[i]);
    for(int i = N - 1; i >= 1; i--) insert(p[i]);
    double ans = 0;
    for(int i = 1; i < top; i++) ans += dis(q[i], q[i + 1]);
    ans += 2 * acos(-1) * L + 0.5;
    printf("%d\n", (int) ans);
}

原文地址:https://www.cnblogs.com/zwfymqz/p/10375835.html

时间: 2024-10-07 11:05:45

POJ 1113 Wall(思维 计算几何 数学)的相关文章

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(

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

题链: http://poj.org/problem?id=1113 题解: 计算几何,凸包 题意:修一圈围墙把给出的点包围起来,且被包围的点距离围墙的距离不能小于L,求围墙最短为多少. 答案其实就是等于N个点的凸包的周长+半径为L的圆的周长. 代码: #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define

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 Wall(标准的凸包果题)

题目链接:http://poj.org/problem?id=1113 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

POJ - 1113 Wall (凸包)

http://poj.org/problem?id=1113 题意 求能包围城堡的最小周长,其中必须与城堡每个点相隔L. 分析 答案是凸包周长加上一个圆周长,即包围凸包的一个圆角多边形. 但那些圆角加起来为什么恰好是一个圆呢?每个圆角是以凸包对应的顶点为圆心,给定的L为半径,与相邻两条边的切点之间的一段圆弧. 每个圆弧的两条半径夹角与对应的凸包的内角互补.假设凸包有n条边,则所有圆弧角之和为180°*n-180°*(n-2)=360°.(凸边形内角和为(n-2)*180) 故,围墙周长为=n条平