poj1113
发布日期:2021-08-26 11:01:58 浏览次数:2 分类:技术文章

本文共 1560 字,大约阅读时间需要 5 分钟。

题意:给出平面上若干个点的坐标,让建一个环形围墙,把所有的点围在里面,且距所有点的距离不小于l。求围墙的最小长度。

分析:凸包周长+半径为l的圆周长

View Code
#include
<
iostream
>
#include
<
cstdio
>
#include
<
cstdlib
>
#include
<
cstring
>
#include
<
cmath
>
#include
<
algorithm
>
using
namespace
std;
#define
maxn 1005
struct
point
{
double
x, y;
} pnt[maxn], res[maxn];
int
n, l;
bool
mult(point sp, point ep, point op)
{
return
(sp.x
-
op.x)
*
(ep.y
-
op.y)
>=
(ep.x
-
op.x)
*
(sp.y
-
op.y);
}
bool
operator
<
(
const
point
&
l,
const
point
&
r)
{
return
l.y
<
r.y
||
(l.y
==
r.y
&&
l.x
<
r.x);
}
int
graham(point pnt[],
int
n, point res[])
{
int
i, len, top
=
1
;
sort(pnt, pnt
+
n);
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
(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
dis(point
&
p, point
&
q)
{
double
x1
=
p.x
-
q.x, y1
=
p.y
-
q.y;
return
sqrt(x1
*
x1
+
y1
*
y1);
}
int
main()
{
//
freopen("t.txt", "r", stdin);
scanf(
"
%d%d
"
,
&
n,
&
l);
for
(
int
i
=
0
; i
<
n; i
++
)
scanf(
"
%lf%lf
"
,
&
pnt[i].x,
&
pnt[i].y);
int
tot
=
graham(pnt, n, res);
double
ans
=
l
*
2
*
3.14159265
;
for
(
int
i
=
0
; i
<
tot; i
++
)
ans
+=
dis(res[i], res[(i
+
1
)
%
tot]);
printf(
"
%.0f\n
"
, ans);
return
0
;
}

转载于:https://www.cnblogs.com/rainydays/archive/2011/06/24/2089193.html

转载地址:https://blog.csdn.net/weixin_33882452/article/details/93673324 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:要么读书,要么旅行,身体和心灵总有一个在路上
下一篇:自动登录苹果id 源代码

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2024年04月09日 10时53分47秒