题目
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
Solution
我们不用怕,直接纯模拟。
我们按照横纵坐标分别排序,然后就可以得出当前镜子将会到达哪个镜子。
有点恶心,不过沉稳地打完,仔细改改就好。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define N 100010
#define LL long long
using namespace std;
const LL fx[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
struct note
{
LL x,y,w,r;
};
note a[N],b[N];
LL i,j,n,m,t,rm,x,y,z,xb,o,mn,c[N];
char ch;
bool cmpy(note a,note b)
{
if (a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
bool cmpx(note a,note b)
{
if (a.y==b.y) return a.x<b.x;
return a.y<b.y;
}
int main()
{
freopen("mir.in","r",stdin);
freopen("mir.out","w",stdout);
scanf("%lld%lld%lld",&n,&m,&t);
mn=10000000001;
fo(i,1,n)
{
scanf("%lld%lld %c\n",&x,&y,&ch);
a[i].x=x;
a[i].y=y;
if (ch=='/') a[i].r=1;
if (y==0)
{
o=1;
if (x>0) mn=min(mn,x);
}
}
a[0].x=a[0].y=1000000001;
sort(a+1,a+n+1,cmpx);
fo(i,1,n) a[i].w=i;
memcpy(b,a,sizeof(b));
sort(b+1,b+n+1,cmpy);
fo(i,1,n) c[b[i].w]=i;
if (!o)
{
printf("%lld %lld",t,0);
return 0;
}
if (t<=mn)
{
printf("%lld %lld",t,0);
return 0;
}
fo(i,1,n)
if (a[i].x==mn && a[i].y==0)
{
xb=i;
break;
}
x=a[xb].x;y=a[xb].y;rm=t-a[xb].x;
if (a[xb].r==1) z=1;else z=3;
while (rm)
{
if (z%2)
{
xb=c[xb];
if (z==1)
{
if (b[xb+1].x==b[xb].x)
{
if (rm<=b[xb+1].y-b[xb].y)
{
printf("%lld %lld",b[xb].x,b[xb].y+rm);
return 0;
}
rm-=b[xb+1].y-b[xb].y;
xb++;
if (b[xb].r==1) z=0;else z=2;
xb=b[xb].w;
} else
{
printf("%lld %lld",b[xb].x,b[xb].y+rm);
return 0;
}
}
if (z==3)
{
if (b[xb-1].x==b[xb].x)
{
if (rm<=b[xb].y-b[xb-1].y)
{
printf("%lld %lld",b[xb].x,b[xb].y-rm);
return 0;
}
rm-=b[xb].y-b[xb-1].y;
xb--;
if (b[xb].r==1) z=2;else z=0;
xb=b[xb].w;
} else
{
printf("%lld %lld",b[xb].x,b[xb].y-rm);
return 0;
}
}
} else
if (z==0 || z==2)
{
if (z==0)
{
if (a[xb+1].y==a[xb].y)
{
if (rm<=a[xb+1].x-a[xb].x)
{
printf("%lld %lld",a[xb].x+rm,a[xb].y);
return 0;
}
rm-=a[xb+1].x-a[xb].x;
xb++;
if (a[xb].r==1) z=1;else z=3;
} else
{
printf("%lld %lld",a[xb].x+rm,a[xb].y);
return 0;
}
}
if (z==2)
{
if (a[xb-1].y==a[xb].y)
{
if (rm<=a[xb].x-a[xb-1].x)
{
printf("%lld %lld",a[xb].x-rm,a[xb].y);
return 0;
}
rm-=a[xb].x-a[xb-1].x;
xb--;
if (a[xb].r==1) z=3;else z=1;
} else
{
printf("%lld %lld",a[xb].x-rm,a[xb].y);
return 0;
}
}
}
}
}