您的位置:首页 > 其它

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

2016-10-29 12:53 525 查看

题目

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
,b
;
LL i,j,n,m,t,rm,x,y,z,xb,o,mn,c
;
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;
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: