【NOIP2016提高A组集训第1场10.29】小W学物理

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.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值