/* 不要低头,不要放弃,不要气馁,不要慌张 题意: 从(0,0)出发与x轴正方向呈45度角的射线,在给定的矩形区域内不断发射,直到射入矩形的某个角停止。 给出多个坐标,问光线最早经过某坐标的时间。 思路: 1.明确光线反射次数不会超过n+m次(好像是这样==没细想) 2.发现规律,光线要么是符合x+y=k,或者x-y=k的直线。而且每次反射都会变到不同类型的直线。 3.知道出发点,算出反射点。 4.把点放到直线的vector里边。每次到了某条直线把直线上的点扫一遍,然后删掉。 */ #include<bits/stdc++.h> using namespace std; struct point{ point(){} point(long long xx,long long yy,int iid){ x=xx;y=yy;id=iid; } long long x,y,id; }; bool operator <(const point &a,const point &b){ if(a.x!=b.x)return a.y<b.y; return a.x<b.x; } set<point> ms1[200050],ms2[200050]; long long rel[100050]; int n,m,k; point next(point a,int num){ if(num&1){ long long w=a.x+a.y; long long x=0; long long y=w-x; if(y>=0&&y<=m&&(x!=a.x||y!=a.y))return point(x,y,0); x=n; y=w-x; if(y>=0&&y<=m&&(x!=a.x||y!=a.y))return point(x,y,0); y=0; x=w-y; if(x>=0&&x<=n&&(x!=a.x||y!=a.y))return point(x,y,0); y=m; x=w-y; if(x>=0&&x<=n&&(x!=a.x||y!=a.y))return point(x,y,0); } else{ long long w=a.x-a.y; long long x=0; long long y=x-w; if(y>=0&&y<=m&&(x!=a.x||y!=a.y))return point(x,y,0); x=n; y=x-w; if(y>=0&&y<=m&&(x!=a.x||y!=a.y))return point(x,y,0); y=0; x=y+w; if(x>=0&&x<=n&&(x!=a.x||y!=a.y))return point(x,y,0); y=m; x=y+w; if(x>=0&&x<=n&&(x!=a.x||y!=a.y))return point(x,y,0); } } long long cal(point a,point b){ return max(a.x-b.x,b.x-a.x); } int main() { memset(rel,-1,sizeof(rel)); long long x,y,bf=0; scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=k;i++){ scanf("%lld%lld",&x,&y); ms1[x-y+100000].insert(point(x,y,i)); ms2[x+y].insert(point(x,y,i)); } point st(0,0,0); int num=0; while(1){ x=st.x;y=st.y; if(num&1){ while(!ms2[x+y].empty()){ long long xx=ms2[x+y].begin()->x; long long yy=ms2[x+y].begin()->y; int id=ms2[x+y].begin()->id; if(rel[id]==-1) rel[id]=bf+cal(point(xx,yy,0),st); ms1[x-y+100000].erase(point(xx,yy,0)); ms2[x+y].erase(point(xx,yy,0)); } } else{ while(!ms1[x-y+100000].empty()){ long long xx=ms1[x-y+100000].begin()->x; long long yy=ms1[x-y+100000].begin()->y; int id=ms1[x-y+100000].begin()->id; if(rel[id]==-1) rel[id]=bf+cal(point(xx,yy,0),st); ms1[x-y+100000].erase(point(xx,yy,0)); ms2[x+y].erase(point(xx,yy,0)); } } bf+=cal(st,next(st,num)); st=next(st,num); num++; if((st.x==0&&st.y==0)||(st.x==0&&st.y==m)||(st.x==n&&st.y==0)||(st.x==n&&st.y==m))break; } for(int i=1;i<=k;i++){ printf("%lld ",rel[i]); } }