codeforces 982E

题解:

先单独处理水平和竖直走的情况,在分析斜着走的情况。

每次我们遇到边界,不反弹,而是接着走,理解为地图向前进的两个方向翻转扩展,直到走到了四个角落之一,算出两个方向各自扩展的数量,在根据奇偶来确定坐标。

利用扩展欧几里得来算出是否有解。

代码:

#include<bits/stdc++.h>
#define N 1000010
#define INF 0x3f3f3f3f
#define LL long long
#define pb push_back
#define cl clear
#define si size
#define lb lowwer_bound
#define eps 1e-8
const LL P=1e9+7;
#define IO ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define P 1000000007;
using namespace std;
LL ex_gcd(LL a, LL b, LL &x, LL &y){
    if (b==0){
        x=1,y=0;
        return a;
    }
    LL q=ex_gcd(b,a%b,y,x);
    y-=a/b*x;
    return q;
}

int main()
{
   	LL n,m,p,q,vx,vy,x,y;
   	cin>>n>>m>>x>>y>>vx>>vy;
   	if (!vx || !vy)
   	{
   		if (vx==0 && vy==0) cout<<-1;else
   		if (vx==0)
   		
   			if (x==0 || x==n)
   				if (vy>0) cout<<x<<' '<<m;else cout<<x<<' '<<0;
   			 else cout<<-1;
   		else
	   		if (vy==0)
	   			if (y==0 || y==m)
	   				if (vx>0) cout<<n<<' '<<y;else cout<<0<<' '<<y;
	   			else cout<<-1;
   	}else
   	{
   		LL gcd=__gcd(n,m);ex_gcd(n,m,p,q);
   		LL t2=n/gcd;
   		if (vx<0) x=n-x;
   		if (vy<0) y=m-y;
		if ((x-y)%gcd !=0)cout<<-1;else
		{
			if (x-y==0) p=m/gcd,q=n/gcd;else
			{
				q*=((x-y)/gcd);q=-q;
				q=(q%t2+t2)%t2;if (!q)q=t2;
				p=(q*m+x-y)/n;
			}
			if (vx>0)if (p%2==0)cout<<0<<' ';else cout<<n<<' ';
			else if (p%2==1)cout<<0<<' ';else cout<<n<<' ';
			if (vy>0)if (q%2==0)cout<<0;else cout<<m;else
			if (q%2==1)cout<<0;else cout<<m;
		}
   	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/nudt_spy/article/details/81260932