您的位置:首页 > 其它

bzoj2829

2015-06-13 14:08 211 查看
裸题,直接上凸包,然后加上一个圆周即可

只是在这之前没写过旋转而已

const pi=3.14159265358979323;
eps=1e-8;
type point=record
x,y:double;
end;

var p:array[0..410010] of point;
q:array[0..410010] of longint;
n,i,k,t:longint;
ans,a,b,x,y,an,r:double;

procedure swap(var a,b:point);
var c:point;
begin
c:=a;
a:=b;
b:=c;
end;

function cmp(a,b:point):boolean;
begin
if abs(a.x-b.x)<eps then exit(a.y<b.y);
exit(a.x<b.x);
end;

procedure sort(l,r:longint);
var i,j:longint;
x:point;
begin
i:=l;
j:=r;
x:=p[(l+r) shr 1];
repeat
while cmp(p[i],x) do inc(i);
while cmp(x,p[j]) do dec(j);
if not(i>j) then
begin
swap(p[i],p[j]);
inc(i);
dec(j);
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end;

function cross(i,j,k:longint):double;
begin
exit((p[i].x-p[k].x)*(p[j].y-p[k].y)-(p[j].x-p[k].x)*(p[i].y-p[k].y));
end;

function dis(i,j:longint):double;
begin
exit(sqrt(sqr(p[i].x-p[j].x)+sqr(p[i].y-p[j].y)));
end;

function get(x,y,x0,y0:double):point;
begin
get.x:=cos(an)*x-sin(an)*y+x0;
get.y:=sin(an)*x+cos(an)*y+y0;
end;

begin
readln(n);
readln(b,a,r);
a:=a-2*r;
b:=b-2*r;
for i:=1 to n do
begin
readln(x,y,an);
inc(t); p[t]:=get(a/2,-b/2,x,y);
inc(t); p[t]:=get(a/2,b/2,x,y);
inc(t); p[t]:=get(-a/2,b/2,x,y);
inc(t); p[t]:=get(-a/2,-b/2,x,y);
end;
sort(1,t);
n:=t;
t:=1;
q[1]:=1;
for i:=2 to n do
begin
while (t>1) and (cross(i,q[t],q[t-1])>=-eps) do dec(t);
inc(t);
q[t]:=i;
end;
k:=t;
for i:=n-1 downto 1 do
begin
while (t>k) and (cross(i,q[t],q[t-1])>=-eps) do dec(t);
inc(t);
q[t]:=i;
end;
for i:=2 to t do
ans:=ans+dis(q[i],q[i-1]);

writeln(ans+2*r*pi:0:2);
end.


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: