?? tju1228.pas
字號:
program tju1228;
const
maxn=10;
maxtimes=9999;//This is just an evaluated amount
//I made a test which occupies 7402 times before merging the equal ones
zero=1e-6;
type
segment=record x1,y1,x2,y2:real;end;
var
umb:array[1..maxn]of record start,len,speed:longint;period,phase:real;end;
time:array[1..maxtimes]of real;
n,wid,duration,vol,i,j,times:longint;
l1,l2,sum:real;
function cross(xa,ya,xb,yb,xc,yc:real):real;
var
x1,y1,x2,y2:real;
begin
x1:=xb-xa;y1:=yb-ya;
x2:=xc-xa;y2:=yc-ya;
cross:=x1*y2-x2*y1;
end;
procedure intersect(a,b:segment);
var
c1,c2,x:real;
begin
c1:=cross(a.x1,a.y1,a.x2,a.y2,b.x1,b.y1);
c2:=cross(a.x1,a.y1,b.x2,b.y2,a.x2,a.y2);
if abs(c1+c2)<zero then exit;
x:=(b.x1*c2+b.x2*c1)/(c1+c2);
if (x>=a.x1-zero) and (x<=a.x2+zero) and
(x>=b.x1-zero) and (x<=b.x2+zero) and (x<duration) then begin
inc(times);time[times]:=x;
end;
end;
procedure make_time(x,y:byte);
var
a,b,c,d:segment;
procedure init(x:byte;var a,b:segment);
begin
with umb[x] do
if speed=0 then begin
with a do begin x1:=0;y1:=start;x2:=duration;y2:=start;end;
with b do begin x1:=0;y1:=start+len;x2:=duration;y2:=start+len;end;
end
else begin
with a do begin
x1:=0;y1:=start;
if speed>0 then begin x2:=(wid-start-len)/speed;y2:=wid-len;end
else begin x2:=-start/speed;y2:=0;end;
end;
with b do begin x1:=0;y1:=start+len;x2:=a.x2;y2:=a.y2+len;end;
end;
end;
procedure advance(x:byte;var a,b:segment);
begin
with umb[x] do begin
with a do begin x1:=x2;y1:=y2;x2:=x2+period/2;y2:=wid-len-y2;end;
with b do begin x1:=x2;y1:=y2;x2:=a.x2;y2:=a.y2+len;end;
end;
if a.x1<duration then begin inc(times);time[times]:=a.x1;end;
end;
begin
init(x,a,b);init(y,c,d);
while (a.x1<duration) and (c.x1<duration) do begin
intersect(a,c);intersect(a,d);
intersect(b,c);intersect(b,d);
if a.x2<c.x2 then advance(x,a,b) else advance(y,c,d);
end;
end;
procedure sort_time(s,t:word);
var
p,i,j:word;
tmp:real;
begin
if s>=t then exit;
p:=s+random(t-s+1);
tmp:=time[p];time[p]:=time[s];
i:=s;j:=t;
repeat
while (i<j) and (time[j]>tmp-zero) do dec(j);
if i=j then break;time[i]:=time[j];inc(i);
while (i<j) and (time[i]<tmp+zero) do inc(i);
if i=j then break;time[j]:=time[i];dec(j);
until i=j;
time[i]:=tmp;
sort_time(s,i-1);
sort_time(i+1,t);
end;
function cover(time:real):real;
var
a:array[1..maxn*2]of real;
d:array[1..maxn*2]of shortint;
i,j,s:shortint;
p:real;
begin
for i:=1 to n do
with umb[i] do begin
if speed=0 then begin
a[i*2-1]:=start;a[i*2]:=start+len;
end
else begin
p:=frac(phase+time/period);
if p>0.5 then p:=1-p;
a[i*2-1]:=(wid-len)*p*2;
a[i*2]:=a[i*2-1]+len;
end;
d[i*2-1]:=1;d[i*2]:=-1;
end;
for i:=1 to n*2-1 do
for j:=i+1 to n*2 do
if a[i]>a[j] then begin
p:=a[i];a[i]:=a[j];a[j]:=p;
s:=d[i];d[i]:=d[j];d[j]:=s;
end;
cover:=0;j:=0;
for i:=1 to n*2 do begin
if j=0 then s:=i;
inc(j,d[i]);
if j=0 then cover:=cover+a[i]-a[s];
end;
end;
begin
repeat
read(n,wid,duration,vol);
for i:=1 to n do
with umb[i] do begin
read(start,len,speed);
if len=wid then speed:=0
else if start=0 then speed:=abs(speed)
else if start=wid-len then speed:=-abs(speed);
if speed=0 then
period:=1e9
else begin
period:=(wid-len)*2/abs(speed);
phase:=start/(wid-len)/2;
if speed<0 then phase:=1-phase;
end;
end;
times:=1;time[1]:=0;
for i:=1 to n-1 do
for j:=i+1 to n do
make_time(i,j);
sort_time(2,times);
j:=times+1;time[j]:=duration;
times:=1;
for i:=1 to j do
if time[i]-time[times]>zero then begin
inc(times);time[times]:=time[i];
end;
sum:=0;l2:=cover(0);
for i:=2 to times do begin
l1:=l2;l2:=cover(time[i]);
sum:=sum+(l1+l2)*(time[i]-time[i-1]);
end;
writeln((wid*duration-sum/2)*vol:0:2);
until seekeof;
end.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -