挖掘机(dig.*)
背景
附中机房谁最虚?高二一班***!感觉很顺,是吧?
题目描述
今天,丧尸czy开着挖掘机去上学(……)。但是他发现他的mz满天下,所以一路上他碰到了好多他的mz。一开始他以1km/min的速度(=60km/h……)开着挖掘机前进。他发现他只会在恰好到达某一时刻或者到达某个距离遇到mz。每次遇到mz,czy都会毫不犹豫的把她们顺路捎走(^_^)。但是他实在是太虚了,以至于当有i个mz时他的速度下降到1/(i+1)。具体说,一开始czy以1km/min速度前进,有1个mz的时候速度变为1/2 km/min,有2个时变为1/3 km/min……以此类推。现在问题来了,给出每个mz在何时出现,请你算出czy到学校要多久。
格式
输入第一行2个数n,m,分别表示mz数和czy与学校的距离(km)
接下来2到n+1行由字符串与数字构成
Dist x表示在距离达到x km时出现一个mz
Time x表示在时间达到x min时出现一个mz
输出一个整数,表示到达学校的时间。如果不能整除,直接输出整数部分即可。
样例输入
2 20
Time 3
Dist 10
样例输出
47
数据范围
对于30%数据,n,m<=50
对于50%数据,n,m<=2000
对于100%数据,n,m<=200000,x<=10^9,保证输入的数字都是整数

type arr=array[0..10000] of longint;
var t,d:arr;
n,m,i,j,x,c,d1,t1,d2,t2,sum:longint;
v,time,tt,pred,s:real;
ans:int64;
ss:string;
procedure sort(l,r: longint;var a:arr);
var
i,j,x,y: longint;
begin
i:=l;
j:=r;
x:=a[(l+r) div 2];
repeat
while a[i]<x do
inc(i);
while x<a[j] do
dec(j);
if not(i>j) then
begin
y:=a[i];
a[i]:=a[j];
a[j]:=y;
inc(i);
j:=j-1;
end;
until i>j;
if l<j then
sort(l,j,a);
if i<r then
sort(i,r,a);
end;
procedure printf;
begin
ans:=trunc(time);
writeln(ans);
halt;
end;
procedure init;
var i:longint;
begin
readln(n,m);
for i:=1 to n do
begin
readln(ss);
x:=pos('Dist',ss);
if x<>0 then
begin
inc(d1);
delete(ss,1,5);
val(ss,d[d1],c);
continue;
end
else
begin
inc(t1);
delete(ss,1,5);
val(ss,t[t1],c);
continue;
end;
end;
end;
procedure change;
begin
// sort(1,t1,t);sort(1,d1,d);
d2:=1;t2:=1;
pred:=0;time:=0;
sum:=0;
v:=1;
//d1:距离出现妹子总数;d2:当前出现的距离妹子的处理
//d1:时间出现妹子总数;d2:当前出现的时间妹子的处理
//sum:当前是第几个妹子
//v:当前速度
//pred:当前走过的路程;time:当前所用时间
end;
procedure main;
begin
while (d2<=d1)and(t2<=t1) do
begin
tt:=(d[d2]-pred)/ v;
if tt+time<=t[t2] then//先碰到距离妹子
begin
time:=time+tt;
inc(sum);
v:=1/(sum+1);
pred:=d[d2];
inc(d2);
continue;
end
else
begin
s:=v*(t[t2]-time);
pred:=pred+s;
time:=t[t2];
inc(sum);
v:=1/(sum+1);
inc(t2);
continue;
end;
end;
if pred=m then printf;
for i:=d2 to d1 do
begin
tt:=(d[d2]-pred)/ v;
time:=time+tt;
pred:=d[d2];
inc(sum);
v:=1/(sum+1);
end;
if pred=m then printf;
for i:=t2 to t1 do
begin
s:=v*(t[t2]-time);
pred:=pred+s;
time:=t[t2];
inc(sum);
v:=1/(sum+1);
end;
if pred=m then printf;
tt:=(m-pred)/ v;
time:=time+tt;
printf;
end;
begin
assign(input,'dig.in');
assign(output,'dig.out');
reset(input);
rewrite(output);
init;
change;
main;
close(input);
close(output);
end.

type arr=array[0..200000] of real;
var t,d:arr;
ans:int64;
n,m,per,i,j,lt,ld,nt:longint;
x,nowt:real;
procedure sort(l,r: longint;var a:arr);
var
i,j:longint;x,y:real;
begin
i:=l;
j:=r;
x:=a[(l+r) div 2];
repeat
while a[i]<x do
inc(i);
while x<a[j] do
dec(j);
if not(i>j) then
begin
y:=a[i];
a[i]:=a[j];
a[j]:=y;
inc(i);
j:=j-1;
end;
until i>j;
if l<j then
sort(l,j,a);
if i<r then
sort(i,r,a);
end;
procedure printf;
begin
ans:=trunc(nowt);
writeln(ans);
halt;
end;
procedure change;
begin
n:=1;
m:=1;
per:=1;
lt:=1;
ld:=1;
nt:=1;
end;
procedure init;
var i,j:longint;ch:char;
begin
readln(n,m);
for i:=1 to n do
begin
read(ch);
if ch='T' then
begin
for j:=1 to 3 do read(ch);
inc(lt);
readln(t[lt]);
end
else
begin
for j:=1 to 3 do read(ch);
inc(ld);
readln(d[ld]);
end;
end;
end;
procedure main;
var nd:real;
begin
inc(ld);
d[ld]:=0.0;
inc(ld);
d[ld]:=m;
for i:=1 to ld-1 do
begin
nd:=d[i];
while (nd<d[i+1])and(nt<=lt)and(nowt+(d[i+1]-nd)*per>t[nt]) do
begin
nd:=nd+(t[nt]-nowt)/per;
inc(per);
nt:=nt+1;
nowt:=t[nt];
end;
nowt:=nowt+(d[i+1]-nd)*per;
inc(per);
end;
end;
begin
assign(input,'dig.in');
assign(output,'dig.out');
reset(input);
rewrite(output);
nowt:=0;
change;
init;
sort(1,ld,d);
sort(1,lt,t);
main;
printf;
close(input);
close(output);
end.
AC程序

program dig;
procedure open;
begin
assign(input,'dig.in');
assign(output,'dig.out') ;
reset(input);
rewrite(output);
end;
procedure closs;
begin
close(input);
close(output);
end;
type zz=array[0..200001] of longint;
var
ch:char;
c,i,n,m,t1,d1,mz,q1,q2:Longint;
t,x:real;
ti,di:zz;
procedure sort(l,r: longint; var a:zz);
var
i,j,x,y: longint;
begin
i:=l;
j:=r;
x:=a[(l+r) div 2];
repeat
while a[i]<x do
inc(i);
while x<a[j] do
dec(j);
if not(i>j) then
begin
y:=a[i];
a[i]:=a[j];
a[j]:=y;
inc(i);
j:=j-1;
end;
until i>j;
if l<j then
sort(l,j,a);
if i<r then
sort(i,r,a);
end;
begin
open;
readln(n,m);
for i:=1 to n do
begin
read(ch);
case ch of
'T':
begin
read(ch); read(ch); read(ch);
inc(t1);
readln(c);
ti[t1]:=c;
end;
'D':
begin
read(ch); read(ch); read(ch);
inc(d1);
readln(c);
di[d1]:=c;
end;
end;
end;
sort(1,t1,ti);
sort(1,d1,di);
q1:=1; q2:=1;
mz:=1;
x:=0; t:=0;
while (q1<=t1) or (q2<=d1) do
begin
if q1<=t1 then
if ((ti[q1]-t)*(1/mz)+x<di[q2]) or (q2=d1+1) then
begin
x:=x+(ti[q1]-t)/mz;
inc(mz);
t:=ti[q1];
inc(q1);
//writeln(x:0:2,' ',t:0:2);
end;
if q2<=d1 then
if ((ti[q1]-t)*(1/mz)+x>di[q2]) or (q1=t1+1) then
begin
t:=t+(di[q2]-x)*mz;
inc(mz);
x:=di[q2];
inc(q2);
//writeln(x:0:2,' ',t:0:2);
end;
if (q2<=d1) and (q1<=t1) then
if ((ti[q1]-t)*(1/mz)+x=di[q2]) then
begin
t:=ti[q1];
x:=di[q2];
inc(mz,2);
inc(q1);
inc(q2);
end;
end;
t:=t+(m-x)*(n+1);
writeln(trunc(t));
closs;
end.
来源:https://www.cnblogs.com/yangqingli/p/4905725.html
