首页 > 其他分享 >POJ 3575(计算几何与二分-无尽的小数处理)

POJ 3575(计算几何与二分-无尽的小数处理)

时间:2022-10-25 12:01:51浏览次数:101  
标签:function begin end 3575 double POJ s2 exit 小数


这题 写了将近半个月……总是在D各种Bug

总的说来-这题最难应该是在精度处理上

1

1

0 0 1

这组数据过了就说明精度处理差不多了……


Program kingdom;
const
maxn=100;
maxm=100;
le=0.000000001;
type
circle=record
x,y,r:double;
end;
var
s:array[1..maxn,1..1000] of circle;
n,i,j,k:longint;
m:array[1..maxn] of longint;
ans:array[1..maxn,1..4] of double;
wanted:array[1..maxn] of double;
b:array[1..maxn] of boolean;
l,r:double;
function arccos(cosa:double):double;
var
sina,tana:double;
begin
if cosa=0 then exit(pi/2);

sina:=sqrt(1-sqr(cosa));
tana:=sina/cosa;
exit(arctan(tana));

end;
function min(a,b:double):double;
begin
if a<b then exit(a) else exit(b);
end;
function max(a,b:double):double;
begin
if a>b then exit(a) else exit(b);
end;

function sector(a,r:double):double;
begin
exit(a*r*r/2);
end;
function triangle(a,r:double):double;
begin
exit(sin(a)*r*r/2);
end;
function inlside(s:circle;l:double):boolean;
begin
if (s.x-s.r>l) or (abs(s.x-s.r-l)<le) then exit(true) else exit(false);
end;
function inrside(s:circle;r:double):boolean;
begin
if (s.x+s.r<r) or (abs(s.x+s.r-r)<le) then exit(true) else exit(false);
end;


function intarea(s:circle;l,r:double):double;
var
i,j:longint;
a,a2,s1,s2,s3,s4:double;
bl,br:boolean;
begin
if (r<s.x-s.r) or (s.x+s.r<l) then exit(0);
if (s.x<=l) then
begin
a:=arccos((l-s.x)/s.r)*2;
if (abs(s.x-l)<le) then s1:=0
else s1:=triangle(a,s.r);
s2:=sector(a,s.r);


if s.x+s.r>r then
begin
a:=arccos((r-s.x)/s.r)*2;
s3:=sector(a,s.r);
s4:=triangle(a,s.r);
s2:=s2-(s3-s4);

end;
exit(s2-s1);
end
else
if (s.x>=r) then
begin
a:=arccos((s.x-r)/s.r)*2;
if (abs(s.x-r)<le) then s1:=0
else s1:=triangle(a,s.r);
s2:=sector(a,s.r);

if s.x-s.r<l then
begin
a:=arccos((s.x-l)/s.r)*2;
s3:=sector(a,s.r);
s4:=triangle(a,s.r);
s2:=s2-(s3-s4);


end;
exit(s2-s1);

end
else
begin
bl:=inlside(s,l);
br:=inrside(s,r);
if bl and br then exit(pi*s.r*s.r);
if bl and not(br) then
begin
a:=arccos((r-s.x)/s.r)*2;
s3:=sector(a,s.r)-triangle(a,s.r);
exit(pi*s.r*s.r-s3);
end;
if not(bl) and br then
begin
a:=arccos((s.x-l)/s.r)*2;
s3:=sector(a,s.r)-triangle(a,s.r);
exit(pi*s.r*s.r-s3);
end;



a:=arccos((s.x-l)/s.r)*2;

a2:=arccos((r-s.x)/s.r)*2;
s1:=sector(2*pi-a-a2,s.r);
s2:=triangle(a,s.r)+triangle(a2,s.r);
exit(s1+s2);



end;



end;
function place(k:longint;l,r:double):boolean;
var
tot:double;
i,j:longint;
begin
tot:=0;
for j:=1 to m[k] do
begin
tot:=tot+intarea(s[k,j],l,r);
end;
// writeln(tot*n,' ',wanted[k]*pi);

if (abs(tot*n-wanted[k]*pi)<le) then exit(true);
if (tot*n<(wanted[k]*pi)) then exit(false) else exit(true);
end;
function bsearch(r1,r2:double):double;
var
m:double;
i,j,k,num:longint;
flag:boolean;
begin
for k:=1 to 60 do
begin
flag:=false;
m:=(r1+r2)/2;
for i:=1 to n do
if not b[i] then
begin
flag:=flag or place(i,l,m);
if flag then
begin
num:=i;
break;
end;
end;
if flag then r2:=m else r1:=m;
end;

b[num]:=true;
ans[num,1]:=l;
ans[num,2]:=r1;

exit(r1);


end;
begin
{ assign(input,'kingdom.in');
reset(input);
} r:=-10000;
l:=10000;
read(n);
fillchar(b,sizeof(b),false);
fillchar(wanted,sizeof(wanted),0);
for i:=1 to n do
begin
read(m[i]);
for j:=1 to m[i] do
begin
read(s[i,j].x,s[i,j].y,s[i,j].r);
// writeln(s[i,j].x,s[i,j].y,s[i,j].r);

r:=max(r,s[i,j].x+s[i,j].r);
l:=min(l,s[i,j].x-s[i,j].r);
wanted[i]:=wanted[i]+sqr(s[i,j].r);

end;
end;
r:=r+1;

for i:=1 to n do
l:=bsearch(l,r);

for i:=1 to n do
begin
writeln('4');
writeln(ans[i,1]:7:7,' 3000');
writeln(ans[i,1]:7:7,' -3000');
writeln(ans[i,2]:7:7,' -3000');
writeln(ans[i,2]:7:7,' 3000');
end;




// close(input);
end.



标签:function,begin,end,3575,double,POJ,s2,exit,小数
From: https://blog.51cto.com/u_15724837/5794421

相关文章

  • POJ 3049(输出字母)
    果断搜ProgramP3049;varn,i,j,m:longint;a:array[1..26]ofchar;b:array['a'..'z']ofboolean;c:char;procedureswap(vara,b:char);vart:char;begin......
  • POJ 3289(高精度乘法)
    高精度乘法ProgramP3289;constmaxn=40000;F=10;typearr=recordd:array[1..maxn]oflongint;len,doc:longint;end;varr,m:arr;y:long......
  • POJ 1222(Gauss消元xor版)
    EXTENDEDLIGHTSOUTDescriptionLightsOut就是下图的游戏,给你一个5*6的矩阵. 你的目标是把灯全关上. 0表示关,1表示开.Input第一行为数据......
  • POJ 2398(二分点集)
    DefaultToyStorageDescription在长方形(x1,y1)(x2,y2)中有n块板(保证与上下边相交),和m个点。现给出板和点的位置,求拥有相同点数的区域数、  Inpu......
  • POJ 2318(点集二分)
    DefaultTOYSDescription在长方形(x1,y1)(x2,y2)中有n块板(保证与上下边相交),和m个点。现给出板和点的位置,求各区域点数、  Input......
  • POJ 1825/2279(Young/Mr. Young's Picture Permutations-杨氏矩阵和钩子公式)
    给出一个n行的矩阵,每一行有a[i]个数,总共有sum个数,要求每一个位置的数必须比上面的数和左面的数大,求总方案数.杨氏矩阵又叫杨氏图表,它是这样一个矩阵,满足条件:(1)如果格子......
  • Java保留2位小数(六种方法)
    一、使用java.math.BigDecimal类publicstaticStringformat1(doublevalue){BigDecimalbd=newBigDecimal(value);bd=bd.setScale(......
  • BigDecimal的加减乘除(包含除法保留两位小数,并不要四舍五入)
    同于经常要用到BigDecimal作数据运算,这里记录一下,总是忘记写法,懒得每次用再去百度了 BigDecimal的加法:BigDecimala=newBigDecimal("1");BigDecimalb=newBigD......
  • PHP保留两位小数的几种方法
    这篇文章主要介绍了PHP保留两位小数的几种方法,需要的朋友可以参考下 代码如下所示:$num=10.4567;//第一种:利用round()对浮点数进行四舍五入echoround($num,2......
  • 小数点的精确方法
    小数点的精确方法1.直接用格式化输出String.format()doubleb=123.4;System.out.println(String.format("%.3f",b));//打印结果为123.400//这里精确到小数点后三位Sys......