UVA 6859 Points(凸包的應用)
傳送門
Peter and Bob are playing a “Points” game on a math sheet of paper. Peter places a few points on the paper — grid nodes. Bob wants to surround them with a polygon so that all marked nodes are lying strictly within (not at the border) the polygon. All sides of the polygon are along the sides or the diagonals of the grid cells and its perimeter is as small as possible. You must determine what is the perimeter of the polygon.
Input
The input file contains several test cases, each of them as described below.
The first line contains integer N — the number of points placed by Peter
Output
For each test case, you need to print one number — the perimeter of the required polygon, on a line by itself. The answer should be printed with accuracy not less than 0.001.
Sample Input
1
0 0
2
1 1
1 2
Sample Output
5.656
7.656854
題目大意:
給定了
解題思路:
其實我們將每個點周圍新增四個點,分別是這個點的上下左右,然後現在一共有
最會答案就是
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;
const double INF = 1e18+5;
const int MAXN = 1e6 + 5;
const double eps = 1e-10;
const double PI = acos(-1.0);
int double_cmp(double x)
{
if(fabs(x) < eps)
return 0;
if(x > 0)
return 1;
return -1;
}
struct Point
{
double x, y;
int id;
Point() {}
Point (double _x, double _y, int i):x(_x),y(_y),id(i) {}
bool operator <(const struct Point &tmp)const
{
if(double_cmp(x-tmp.x) == 0)
return double_cmp(y-tmp.y) < 0;
return double_cmp(x-tmp.x) < 0;
}
bool operator == (const struct Point &tmp)const
{
return double_cmp(x-tmp.x)==0&&double_cmp(y-tmp.y)==0;
}
} p[MAXN],st[MAXN];
bool cmp(const Point& p1, const Point& p2)
{
return atan2(p1.y, p1.x) < atan2(p2.y, p2.x);
}
double XMulti(Point a, Point b, Point c)///ac X ab
{
return (c.x-a.x)*(b.y-a.y) - (b.x-a.x)*(c.y-a.y);
}
double dis(Point a, Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
double dis2(Point a, Point b)
{
return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);
}
double dot(Point a, Point b, Point c)///點積 ab . ac
{
double s1 = b.x-a.x;
double t1 = b.y-a.y;
double s2 = c.x-a.x;
double t2 = c.y-a.y;
return s1*s2 + t1*t2;
}
int ConvexHull(Point *p, int n, Point *st)///凸包
{
sort(p, p+n);
n = unique(p, p+n)-p;///去重
int m = 0;
for(int i=0; i<n; i++)
{
while(m>1 && XMulti(st[m-2],p[i],st[m-1])<=0)
m--;
st[m++] = p[i];
}
int k = m;
for(int i=n-2; i>=0; i--)
{
while(m>k && XMulti(st[m-2],p[i],st[m-1])<=0)
m--;
st[m++] = p[i];
}
if(n > 1)
m--;
return m;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
int sum = 0;
for(int i=0; i<n; i++)
{
double xx, yy;
scanf("%lf%lf",&xx,&yy);
p[sum].x = xx+1, p[sum++].y = yy;
p[sum].x = xx-1, p[sum++].y = yy;
p[sum].x = xx, p[sum++].y = yy+1;
p[sum].x = xx, p[sum++].y = yy-1;
}
int cnt = ConvexHull(p, sum, st);
double sum1 = 0, sum2 = 0;
double dx, dy;
dx = fabs(st[0].x-st[cnt-1].x);
dy = fabs(st[0].y-st[cnt-1].y);
sum1 += min(dx, dy);
sum2 += fabs(dx-dy);
for(int i=1; i<cnt; i++){
dx = fabs(st[i].x-st[i-1].x);
dy = fabs(st[i].y-st[i-1].y);
sum1 += min(dx, dy);
sum2 += fabs(dx-dy);
}
///cout<<sum1<<" "<<sum2<<endl;
double ans = sum1*sqrt(2.0)+sum2;
printf("%.6lf\n",ans);
}
return 0;
}