Codeforces 982E Billiard 擴展歐幾里得+思維

本文參考自: 原文地址


E. Billiard
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Consider a billiard table of rectangular size n×mn×m with four pockets. Let's introduce a coordinate system with the origin at the lower left corner (see the picture).

There is one ball at the point (x,y)(x,y) currently. Max comes to the table and strikes the ball. The ball starts moving along a line that is parallel to one of the axes or that makes a 4545∘ angle with them. We will assume that:

  1. the angles between the directions of the ball before and after a collision with a side are equal,
  2. the ball moves indefinitely long, it only stops when it falls into a pocket,
  3. the ball can be considered as a point, it falls into a pocket if and only if its coordinates coincide with one of the pockets,
  4. initially the ball is not in a pocket.

Note that the ball can move along some side, in this case the ball will just fall into the pocket at the end of the side.

Your task is to determine whether the ball will fall into a pocket eventually, and if yes, which of the four pockets it will be.

Input

The only line contains 66 integers nnmmxxyyvxvxvyvy (1n,m1091≤n,m≤1090xn0≤x≤n0ym0≤y≤m1vx,vy1−1≤vx,vy≤1(vx,vy)(0,0)(vx,vy)≠(0,0)) — the width of the table, the length of the table, the xx-coordinate of the initial position of the ball, the yy-coordinate of the initial position of the ball, the xx-component of its initial speed and the yy-component of its initial speed, respectively. It is guaranteed that the ball is not initially in a pocket.

Output

Print the coordinates of the pocket the ball will fall into, or 1−1 if the ball will move indefinitely.

Examples
input
Copy
4 3 2 2 -1 1
output
Copy
0 0
input
Copy
4 4 2 0 1 1
output
Copy
-1
input
Copy
10 10 10 1 -1 0
output
Copy
-1
Note

The first sample:

The second sample:

In the third sample the ball will never change its yy coordinate, so the ball will never fall into a pocket.


反射後的路徑相當於之前的路徑延以前方向繼續伸展,然後和碰撞的邊做對稱變換得到。所以我們把整張圖展開。方便計算,我們把原圖所有45°的方向全部調整爲向右上角。在這個基礎上,反向延長出發方向所在的射線,並與圖的邊相交。經過一番推導,發現本題的解是滿足a*n+b*m=x-y的最小整數a。於是使用擴展歐幾里得求解。

#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;

int n,m,x,y,vx,vy;

long long exgcd(long long a,long long b,long long &x,long long &y)
{
    if (b==0)
    {
        x=1; y=0; return a;
    }
    long long r=exgcd(b,a%b,x,y);
    long long t=x; x=y;
    y=t-a/b*y;
    return r;
}

int main()
{
    scanf("%d%d%d%d%d%d",&n,&m,&x,&y,&vx,&vy);
    if (vx*vy==0)
    {
        if (x>0 && y>0 && x<n &&y<m)
        {
            cout<<-1<<endl;
            return 0;
        }else
        {
            if (vy==1 && x==0 || vx==-1 && y==m)
            {
                cout<<"0 "<<m<<endl; return 0;
            }else if (vy==-1 && x==0 || vx==-1 && y==0)
            {
                cout<<"0 0"<<endl; return 0;
            }else if (vx==1 && y==0 || vy==-1 && x==n)
            {
                cout<<n<<" 0"<<endl; return 0;
            }else if (vy==1 && x==n || vx==1 && y==m)
            {
                cout<<n<<' '<<m<<endl; return 0;
            }else
            {
                cout<<-1<<endl;
                return 0;
            }
        }
    }
    bool flagx=false;
    bool flagy=false;
    if (vx==-1)
    {
        flagx=true; x=n-x;
    }
    if (vy==-1)
    {
        flagy=true; y=m-y;
    }
    long long a=n;
    long long b=m;
    long long c=x-y;
    long long xx,yy;
    long long d=exgcd(a,b,xx,yy);
    if (c%d!=0)
    {
        cout<<-1<<endl;
        return 0;
    }
    a=a/d;
    b=b/d;
    c=c/d;
    if (b<0) b=-b;
    //cout<<"!="<<xx<<" !="<<yy<<endl;
    xx=xx*c;
    //cout<<"x="<<xx<<endl;
    if (xx%b<=0) xx=xx%b+b;
    else xx=xx%b;
    yy=-(x-y-xx*n)/m;
    //cout<<"a="<<xx<<" b="<<yy<<endl;
    long long p=0; long long q=0;
    if (xx%2) p=n;
    if (yy%2) q=m;
    if (flagx) p=n-p;
    if (flagy) q=m-q;
    cout<<p<<' '<<q<<endl;
    return 0;
}

發佈了39 篇原創文章 · 獲贊 2 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章