Billiard CFR484 div2 (数论)

就是一个点从开始的点在一个矩形内往某个方向一直运动,如果碰到了矩形的边,那么就反弹,我们可以把这个矩形拓展开,那么就是问题变成了我有没有一个点,这个点的坐标(Tx, Ty)满足n|Tx,m|Ty

那么假设有的话,那么这个直线的方程化简以后就是就是n*xx+m*yy = y-x,然后问题就变成了这个方程有没有解,如果我无解,那么就是-1,如果有解,那么就求出xx和yy的最小值,然后通过xx,yy的奇偶性来判断我进入边界的位置是哪里.

这是对于方向在右上角的,对于其他方向上我们可以转化到右上角,比如如果是左上角,那么就可以让现在的x = n - x, 最后的答案xx进行相应的变化 xx = n - xx,其他方向同理。

#include<map>
#include<set>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define first fi
#define second se
#define lowbit(x) (x & (-x))

typedef unsigned long long int ull;
typedef long long int ll;
const double pi = 4.0*atan(1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 500005;
const int maxm = 305;
using namespace std;

int n, m, tol, T;

ll e_gcd(ll a, ll b, ll &x, ll &y) {
    if(b == 0) {
        x = 1;
        y = 0;
        return a;
    } else {
        ll d = e_gcd(b, a%b, x, y);
        ll tmp = y;
        y = x - a/b*y;
        x = tmp;
        return d;
    }
}

int main() {
    int x,y,vx,vy;
    scanf("%d%d%d%d%d%d", &n, &m, &x, &y, &vx, &vy);
    if(vx == 0 && vy == 0) {
        printf("-1\n");
        return 0;
    }
    if(vx == 0) {
        if(x == n || x == 0) {
            if(vy == 1)
                printf("%d %d\n", x, m);
            else
                printf("%d %d\n", x, 0);
        } else {
            printf("-1\n");
        }
        return 0;
    }
    if(vy == 0) {
        if(y == m || y == 0) {
            if(vx == 1)
                printf("%d %d\n", n, y);
            else
                printf("%d %d\n", 0, y);
        } else {
            printf("-1\n");
        }
        return 0;
    }
    bool fx = false;
    bool fy = false;
    if(vx == -1) {
        fx = true;
        x = n - x;
    }
    if(vy == -1) {
        fy = true;
        y = m - y;
    }
    ll a = n;
    ll b = m;
    ll c = x - y;
    ll xx, yy;
    ll d = e_gcd(a, b, xx, yy);
    if(c % d) {
        printf("-1\n");
        return 0;
    }
    ll r = b / d;
    ll cx = ((c/d) * xx % r + r + r - 1) %r + 1;
    ll cy = (cx * n - c) / m;
    ll ansx, ansy;
    if(cx & 1) {
        ansx = n;
    } else {
        ansx = 0;
    }
    if(cy & 1) {
        ansy = m;
    } else {
        ansy = 0;
    }
    if(fx)    ansx = (ll)n - ansx;
    if(fy)    ansy = (ll)m - ansy;
    printf("%lld %lld\n", ansx, ansy);
    return 0;
}
View Code

 

posted @ 2018-07-24 17:49  Jiaaaaaaaqi  阅读(141)  评论(0编辑  收藏  举报