Description
为了测试小W的物理水平,Mr.X在二维坐标系中放了N面镜子(镜子坐标绝对值不超过M),镜子均与坐标轴成45°角,所以一共有两种类型“/”和“\”。原点不会有镜子,任意一点最多只有一面镜子。
镜子两个面都能反光,而中间不透光,例如,对于一个“/”型镜子,下方向射入的光线会被反射到右方向,左方向射入的光线会被反射到上方向。
现在有一条光线从原点沿X轴正方向射出,求走过T路程后所在位置。
Input
第一行三个整数N,M,T。
第2到N+1行,每行两个整数Xi,Yi,表示镜子坐标,一个字符Si表示镜子类型
Output
一行两个整数,表示走过T路程后的坐标。
Sample Input
5 2 8
0 1 \
0 2 /
1 0 /
1 1 \
1 2 \
Sample Output
3 1
Data Constraint
对于10%的数据:N=1
对于25%的数据:T<=1000000
对于35%的数据:N<=1000
对于60%的数据:M<=1000
对于100%的数据:N<=100,000,M<=1,000,000,000,T<=10^18
方法
预处理出每一个点上下左右的第一个点
然后直接模拟
贴代码
品尝痛苦吧!
var
bz:array[0..100005,1..4]of boolean;
go:array[0..100005,1..4]of longint;
a,sh,xi,zu,yo:array[0..100005,1..3]of longint;
s1,x1,z1,y1:array[0..100005]of longint;
s:array[0..100005]of char;
i,j,k,l,n,m,x,y,going:longint;
ju,t:int64;
procedure qsort(l,r:longint);
var
i,j,mid,mid1:longint;
begin
i:=l;
j:=r;
mid:=a[(i+j) div 2,1];
mid1:=a[(i+j) div 2,2];
repeat
while (a[i,1]<mid) or ((a[i,1]=mid) and (a[i,2]<mid1)) do inc(i);
while (a[j,1]>mid) or ((a[j,1]=mid) and (a[j,2]>mid1)) do dec(j);
if i<=j then
begin
a[0]:=a[i];
a[i]:=a[j];
a[j]:=a[0];
inc(i);
dec(j);
end;
until i>j;
if i<r then qsort(i,r);
if l<j then qsort(l,j);
end;
procedure qsort1(l,r:longint);
var
i,j,mid,mid1:longint;
begin
i:=l;
j:=r;
mid:=a[(i+j) div 2,2];
mid1:=a[(i+j) div 2,1];
repeat
while (a[i,2]<mid) or ((a[i,2]=mid) and (a[i,1]<mid1)) do inc(i);
while (a[j,2]>mid) or ((a[j,2]=mid) and (a[j,1]>mid1)) do dec(j);
if i<=j then
begin
a[0]:=a[i];
a[i]:=a[j];
a[j]:=a[0];
inc(i);
dec(j);
end;
until i>j;
if i<r then qsort1(i,r);
if l<j then qsort1(l,j);
end;
procedure qsort2(l,r:longint);
var
i,j,mid:longint;
begin
i:=l;
j:=r;
mid:=a[(i+j) div 2,3];
repeat
while a[i,3]<mid do inc(i);
while a[j,3]>mid do dec(j);
if i<=j then
begin
a[0]:=a[i];
a[i]:=a[j];
a[j]:=a[0];
inc(i);
dec(j);
end;
until i>j;
if i<r then qsort2(i,r);
if l<j then qsort2(l,j);
end;
procedure bye_bye;
begin
close(input); close(output);
halt;
end;
begin
// assign(input,'t2.in'); reset(input);
assign(input,'mir.in'); reset(input);
assign(output,'mir.out'); rewrite(output);
readln(n,m,t);
for i:=1 to n do
begin
readln(a[i,1],a[i,2],s[i],s[i]);
a[i,3]:=i;
if s[i]='/' then
begin
z1[i]:=2;
s1[i]:=1;
y1[i]:=4;
x1[i]:=3;
end else
begin
z1[i]:=4;
s1[i]:=3;
y1[i]:=2;
x1[i]:=1;
end;
end;
qsort(1,n);
for i:=2 to n do
if a[i,1]=a[i-1,1] then
begin
sh[a[i-1,3],1]:=a[i,3];
sh[a[i-1,3],2]:=a[i,2]-a[i-1,2];
xi[a[i,3],1]:=a[i-1,3];
xi[a[i,3],2]:=a[i,2]-a[i-1,2];
end;
qsort1(1,n);
for i:=2 to n do
if a[i,2]=a[i-1,2] then
begin
yo[a[i-1,3],1]:=a[i,3];
yo[a[i-1,3],2]:=a[i,1]-a[i-1,1];
zu[a[i,3],1]:=a[i-1,3];
zu[a[i,3],2]:=a[i,1]-a[i-1,1];
end;
for y:=1 to n do
if (a[y,2]=0) and (a[y,1]>0) then break;
if a[y,2]<>0 then writeln(t,' ',0) else
begin
ju:=abs(a[y,1]);
bz[a[y,3],3]:=true;
go[a[y,3],3]:=abs(a[y,1]);
x:=a[y,3];
qsort2(1,n);
if s[x]='/' then going:=2 else going:=4;
while ju<t do
begin
if going=3 then
begin
if (yo[x,1]=0) or (yo[x,2]>=t-ju) then
begin
writeln(a[x,1]+t-ju,' ',a[x,2]);
bye_bye;
end;
ju:=ju+yo[x,2];
if bz[yo[x,1],3]=true then
begin
t:=t-ju;
t:=t mod (ju-go[yo[x,1],3]);
ju:=0;
end else go[yo[x,1],3]:=ju;
bz[yo[x,1],3]:=true;
x:=yo[x,1];
if s[x]='/' then going:=2 else going:=4;
end else
if going=1 then
begin
if (zu[x,1]=0) or (zu[x,2]>=t-ju) then
begin
writeln(a[x,1]+ju-t,' ',a[x,2]);
bye_bye;
end;
ju:=ju+zu[x,2];
if bz[zu[x,1],1]=true then
begin
t:=t-ju;
t:=t mod (ju-go[zu[x,1],1]);
ju:=0;
end else go[zu[x,1],1]:=ju;
bz[zu[x,1],1]:=true;
x:=zu[x,1];
if s[x]='/' then going:=4 else going:=2;
end else
if going=4 then
begin
if (xi[x,1]=0) or (xi[x,2]>=t-ju) then
begin
writeln(a[x,1],' ',a[x,2]+ju-t);
bye_bye;
end;
ju:=ju+xi[x,2];
if bz[xi[x,1],2]=true then
begin
t:=t-ju;
t:=t mod (ju-go[xi[x,1],2]);
ju:=0;
end else go[xi[x,1],2]:=ju;
bz[xi[x,1],2]:=true;
x:=xi[x,1];
if s[x]='/' then going:=1 else going:=3;
end else
if going=2 then
begin
if (sh[x,1]=0) or (sh[x,2]>=t-ju) then
begin
writeln(a[x,1],' ',a[x,2]+t-ju);
bye_bye;
end;
ju:=ju+sh[x,2];
if bz[sh[x,1],4]=true then
begin
t:=t-ju;
t:=t mod (ju-go[sh[x,1],4]);
ju:=0;
end else go[sh[x,1],4]:=ju;
bz[sh[x,1],4]:=true;
x:=sh[x,1];
if s[x]='/' then going:=3 else going:=1;
end;
end;
end;
close(input); close(output);
end.