给你一个光纤,45度射出,然后求碰到每个球的第一次的时间
模拟可搞,因为墙上就40W个点,然后对于墙上每个点,有2个方向过来的
预处理墙上每个点每个方向来的第一次时间
然后对于每个点,直接往四周看就行了
其实可以计算,有4种情况,exgcd可解,但是容易错把,不写了
代码:
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
#define MAX 100005
#define MAXN 1000005
#define maxnode 105
#define sigma_size 30
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lrt rt<<1
#define rrt rt<<1|1
#define middle int m=(r+l)>>1
#define LL long long
#define ull unsigned long long
#define mem(x,v) memset(x,v,sizeof(x))
#define lowbit(x) (x&-x)
#define pii pair<int,int>
#define bits(a) __builtin_popcount(a)
#define mk make_pair
#define limit 10000
//const int prime = 999983;
const int INF = 0x3f3f3f3f;
const LL INFF = 0x3f3f;
const double pi = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-6;
const LL mod = 1e9+7;
const ull mx = 133333331;
/*****************************************************/
inline void RI(int &x) {
char c;
while((c=getchar())<'0' || c>'9');
x=c-'0';
while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0';
}
/*****************************************************/
int a[MAX],b[MAX];
LL vis[MAX][4][4];
int main(){
//freopen("in.txt","r",stdin);
int n,m,k;
while(cin>>n>>m>>k){
for(int i=0;i<k;i++){
scanf("%d%d",&a[i],&b[i]);
}
mem(vis,-1);
int tmp=0;
int x=0,y=0;
LL ti=0;
//cout<<vis[0][0][0]<<endl;
while(1){
if(tmp==0){
if((n-x)+y==m) break;
if((n-x)+y<m){
vis[(n-x)+y][3][0]=ti+n-x;
ti=ti+n-x;
y=(n-x)+y;
x=n;
tmp=3;
}
else{
vis[x+(m-y)][2][0]=ti+m-y;
ti=ti+m-y;
x=x+(m-y);
y=m;
tmp=1;
}
}
else if(tmp==1){
if(y-(n-x)==0) break;
if(y>n-x){
vis[y-(n-x)][3][1]=ti+(n-x);
ti=ti+(n-x);
y=y-(n-x);
x=n;
tmp=2;
}
else{
vis[x+y][0][1]=ti+y;
ti=ti+y;
x=x+y;
y=0;
tmp=0;
}
}
else if(tmp==2){
if(x==y) break;
if(x<y){
vis[y-x][1][2]=ti+x;
ti=ti+x;
y=y-x;
x=0;
tmp=1;
}
else{
vis[x-y][0][2]=ti+y;
ti=ti+y;
x=x-y;
y=0;
tmp=3;
}
}
else if(tmp==3){
if(y+x==m) break;
if(y+x<m){
vis[y+x][1][3]=ti+x;
ti=ti+x;
y=y+x;
x=0;
tmp=0;
}
else{
vis[x-(m-y)][2][3]=ti+(m-y);
ti=ti+(m-y);
x=x-(m-y);
y=m;
tmp=2;
}
}
}
for(int i=0;i<k;i++){
LL ans=1e18;
if(a[i]==b[i]){
printf("%d\n",a[i]);
continue;
}
if((n-a[i])+b[i]>m){
if(vis[a[i]+(m-b[i])][2][3]!=-1){
ans=min(ans,vis[a[i]+(m-b[i])][2][3]+m-b[i]);
}
}
if((n-a[i])+b[i]<m){
if(vis[b[i]+n-a[i]][3][1]!=-1){
ans=min(ans,vis[b[i]+n-a[i]][3][1]+n-a[i]);
}
}
if(b[i]>n-a[i]){
if(vis[b[i]-(n-a[i])][3][0]!=-1){
ans=min(ans,vis[b[i]-(n-a[i])][3][0]+n-a[i]);
}
}
if(b[i]<n-a[i]){
if(vis[a[i]+b[i]][0][2]!=-1){
ans=min(ans,vis[a[i]+b[i]][0][2]+b[i]);
}
}
if(a[i]<b[i]){
if(vis[b[i]-a[i]][1][3]!=-1){
ans=min(ans,vis[b[i]-a[i]][1][3]+a[i]);
}
}
if(a[i]>b[i]){
if(vis[a[i]-b[i]][0][1]!=-1){
ans=min(ans,vis[a[i]-b[i]][0][1]+b[i]);
}
}
if(a[i]+b[i]>m){
if(vis[a[i]-(m-b[i])][2][0]!=-1){
ans=min(ans,vis[a[i]-(m-b[i])][2][0]+(m-b[i]));
}
}
if(a[i]+b[i]<m){
if(vis[a[i]+b[i]][1][2]!=-1){
ans=min(ans,vis[a[i]+b[i]][1][2]+a[i]);
}
}
if(ans!=1e18) printf("%I64d\n",ans);
else printf("-1\n");
}
}
return 0;
}