【JZOJ4823】小W学物理

Description

为了测试小W的物理水平,Mr.X在二维坐标系中放了N面镜子(镜子坐标绝对值不超过M),镜子均与坐标轴成45°角,所以一共有两种类型“/”和“\”。原点不会有镜子,任意一点最多只有一面镜子。
镜子两个面都能反光,而中间不透光,例如,对于一个“/”型镜子,下方向射入的光线会被反射到右方向,左方向射入的光线会被反射到上方向。
现在有一条光线从原点沿X轴正方向射出,求走过T路程后所在位置。

Solution

结论1:如果光线不形成环,那么每面镜子至多经过两次。

结论2:如果光线形成环,那么光线通过反射后一定重新经过原点。

那么直接模拟光线走到哪即可。

注意特判一些情况。

数据水,不判环可以过。

Code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define N 100001
#define ll long long
using namespace std;
struct node{
    ll x,y;
    int z,c;
}a[N],zx[N],zy[N];
int cx[N],cy[N];
ll bz[N][2][2];
bool cmpx(node x,node y)
{
    if(x.x==y.x) return x.y<y.y;
    else return x.x<y.x;
}
bool cmpy(node x,node y)
{
    if(x.y==y.y) return x.x<y.x;
    else return x.y<y.y;
}
ll abss(ll x){
    return x<0?-x:x;
}
node pp;
int main()
{
    freopen("mir.in","r",stdin);
    freopen("mir.out","w",stdout);
    int n;
    ll m,t;
    cin>>n>>m>>t;
    fo(i,1,n)
    {
        char ch;
        scanf("%lld %lld %c",&pp.x,&pp.y,&ch);
        if(ch=='/') pp.z=1;
        else pp.z=-1;
        a[i]=zx[i]=zy[i]=pp;
    }
    sort(a+1,a+n+1,cmpx);
    fo(i,1,n) a[i].c=i;
    sort(a+1,a+n+1,cmpy);
    fo(i,1,n) cx[a[i].c]=i,a[i].c=i;
    sort(a+1,a+n+1,cmpx);
    fo(i,1,n) cy[a[i].c]=i;
    sort(zx+1,zx+n+1,cmpx);
    sort(zy+1,zy+n+1,cmpy);
    int p=0,q=0;
    fo(i,1,n)
    if(zy[i].y==0 && zy[i].x>0)
    {
        p=cy[i];
        break;
    }
    ll s=zx[p].x,ss;
    if(s>=t || !p)
    {
        printf("%lld 0",t);
        return 0;
    }
    int z=zx[p].z,fx=1;
    bz[p][fx][1]=s;
    while(s<t)
    {
        ss=s;
        if(fx==1)
        {
            q=p;
            p+=z;
            if(zx[p].x!=zx[q].x)
            {
                printf("%lld %lld",zx[q].x,zx[q].y+z*(t-s));
                break;
            }
            s+=abss(zx[p].y-zx[q].y);
            if(s>=t)
            {
                printf("%lld %lld",zx[q].x,zx[q].y+z*(t-ss));
                break;
            }
            fx=0;
        }
        else
        {
            q=p;
            p=cy[cx[p]+z];
            if(zx[p].y!=zx[q].y)
            {
                printf("%lld %lld",zx[q].x+z*(t-s),zx[q].y);
                return 0;
            }
            s+=abss(zx[p].x-zx[q].x);
            if(s>=t)
            {
                printf("%lld %lld",zx[q].x+z*(t-ss),zx[q].y);
                break;
            }
            fx=1;
        }
        int zz=z;
        if(zz==-1) zz++;
        if(bz[p][fx][zz])
        {
            ll s1=s-bz[p][fx][zz];
            ll s2=t-s;
            s+=(s2/s1)*s1;
        }
        bz[p][fx][zz]=s;
        z*=zx[p].z;
    }
}
posted @ 2016-10-29 14:41  sadstone  阅读(56)  评论(0编辑  收藏  举报