UVAlive 6859 Points(凸包)

题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4871

思路:将所有点上下左右四个点构成的集合求一遍凸包,边长不能直接计算(正确结果可能不为凸包)。

边长计算用下列式子:

x=fabs(a.x-b.x)

y=fabs(a.y-b.y)

c=fabs(x-y)+min(x,y)*sqrt(2)

(若答案最小则应尽量选择更多斜边)

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const double eps=1e-10;
const int maxn=4e5+50;
struct Point
{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y) {}
};
typedef Point Vector;
Vector operator + (Vector A,Vector B)
{
    return Vector(A.x+B.x,A.y+B.y);
}
Vector operator - (Point A,Point B)
{
    return Vector(A.x-B.x,A.y-B.y);
}
Vector operator * (Vector A,double p)
{
    return Vector(A.x*p,A.y*p);
}
int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    else return x<0?-1:1;
}
double Cross(Vector A,Vector B)
{
    return A.x*B.y-A.y*B.x;
}
int cmp(Point a,Point b)
{
    if(a.x==b.x) return a.y<b.y;
    else return a.x<b.x;
}
int ConvexHull(Point* p,int n,Point* ch)
{
    sort(p,p+n,cmp);
    int m=0;
    for(int i=0; i<n; i++)
    {
        while(m>1&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
        ch[m++]=p[i];
    }
    int k=m;
    for(int i=n-2; i>=0; i--)
    {
        while(m>k&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
        ch[m++]=p[i];
    }
    if(n>1) m--;
    return m;
}
double dist(Point a,Point b)
{
    double x=fabs(a.x-b.x);
    double y=fabs(a.y-b.y);
    return fabs(x-y)+min(x,y)*sqrt(2);
}
int n;
Point ch[maxn],p[maxn];
int main()
{
    while(scanf("%d",&n)==1)
    {
        int tot=0;
        for(int i=0; i<n; i++)
        {
            double x,y;
            scanf("%lf%lf",&x,&y);
            p[tot++]=Point(x-1,y);
            p[tot++]=Point(x+1,y);
            p[tot++]=Point(x,y+1);
            p[tot++]=Point(x,y-1);
        }
        memset(ch,0,sizeof(ch));
        double ans=0.0;
        int num=ConvexHull(p,tot,ch);
        for(int i=0;i<num;i++)
            ans+=dist(ch[i],ch[(i+1)%num]);
        printf("%.4f\n",ans);
    }
    return 0;
}
时间: 2024-10-11 22:37:10

UVAlive 6859 Points(凸包)的相关文章

LA UVaLive 6859 Points (几何,凸包)

题意:给定 n 个点,让你用最长的周长把它们严格包围起来,边长只能用小格子边长或者是小格子对角线. 析:先把每个点的上下左右都放到一个集合中,然后求出一个凸包,然后先边长转成题目的方式,也好转两个点的最小的*根号2加上两者差*1. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdli

UVALive 7281 求凸包 并判断点是否在凸包内

题解 二分判断点在凸包内,把凸包分成以p0为顶点的tot-2个三角形,判断是否有一个三角形把所要判断的点包住 #include<cstdio> #include<iostream> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int n,m,tot; struct point { double

Soj题目分类

-----------------------------最优化问题------------------------------------- ----------------------常规动态规划  SOJ1162 I-Keyboard  SOJ1685 Chopsticks SOJ1679 Gangsters SOJ2096 Maximum Submatrix  SOJ2111 littleken bg SOJ2142 Cow Exhibition  SOJ2505 The County

二维几何基本操作

刘汝佳白皮书模板 #include<bits/stdc++.h> using namespace std; const double PI=acos(-1); const int INF=1<<20; struct Point{//定义点 double x,y; Point (double x=0,double y=0):x(x),y(y){} }p[10000]; typedef Point Vector;//定义向量 Vector operator +(Vector A,Vec

UVALive 4639 &amp;&amp; SPOJ SPOINTS &amp;&amp; POJ 3805 &amp;&amp; AOJ 1298 Separate Points 求两个凸包是否相交 难度:3

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2640 http://www.spoj.com/problems/SPOINTS/en/ http://poj.org/problem?id=3805 http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1298 要

UVALive 4986 Dome of Circus(三分、凸包、凸性函数)

题目链接: UVALive 4986 Dome of Circus 题意: 在空间中给n个点的坐标,并且每个点都是在z轴的正半平面内,以原点(0,0,0)为底面圆圆心,画一个圆锥,要求圆锥要包含所有的点,点可以在圆锥面上,求最小的圆锥体积的底面圆半径和高. 数据范围:1≤n≤10000,并且所有点的坐标的绝对值都不超过10000 分析: 首先把三维的点转成二维的,因为是圆锥覆盖,所以我们只需要知道点到圆锥轴的距离和点的纵坐标就好了.那么可得: (x,y,z)→(x2+y2??????√,z) 这

poj 3787 Convex Hull of Lattice Points 求凸包

题意: 裸的凸包. 分析: graham模板直接上. 代码: //poj 3787 //sep9 #include <iostream> #include <algorithm> using namespace std; const int maxN=64; struct P { int x,y; }pnt[maxN],cnt[maxN]; int n; int cmp(P a,P b) { if(a.y!=b.y) return a.y<b.y; return a.x<

POJ 3090 ZOJ 2777 UVALive 3571 Visible Lattice Points(用递推比用欧拉函数更好)

题目: Description A lattice point (x, y) in the first quadrant (x and y are integers greater than or equal to 0), other than the origin, is visible from the origin if the line from (0, 0) to (x, y) does not pass through any other lattice point. For exa

UVALIVE 3571 Visible Lattice Points

就欧拉函数然后地推一下. #include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include <cstdio> #include <st