Codeforces 982E Billiard exgcd

Billiard

枚举终点, 对于每一个终点一共有四种周期的相遇方式, 枚举一下取最小的时间。

#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long

using namespace std;

const int N = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double PI = acos(-1);

template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;}
template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;}

LL x, y;
LL exgcd(LL a, LL b, LL &x, LL &y) {
    if(!b) {
        x = 1; y = 0;
        return a;
    } else {
        LL gcd, t; gcd = exgcd(b, a % b, x, y);
        t = x; x = y; y = t - (a / b) * y;
        return gcd;
    }
}


LL n, m, sx, sy, vx, vy;

LL gao(LL a, LL b, LL t1, LL t2) {
    LL c = t2 - t1;
    LL gcd = exgcd(a, b, x, y);
    if(c % gcd) return INF;
    x *= c / gcd; y *= c / gcd;
    LL mo = abs(b / gcd);
    x = (x % mo + mo) % mo;
    return 2 * n * x + t1;
}

LL calc(LL sx, LL sy, LL vx, LL vy, LL tx, LL ty) {
    LL t11 = 0, t12 = 0;
    LL t21 = 0, t22 = 0;
    if(vx > 0) {
        if(tx >= sx) t11 = tx - sx, t12 = t11 + 2 * (n - tx);
        else t11 = sx - tx + 2 * (n - sx), t12 = t11 + 2 * tx;
    } else {
        if(tx <= sx) t11 = sx - tx, t12 = t11 + 2 * tx;
        else t11 = tx - sx + 2 * sx, t12 = t11 + 2 * (n - tx);
    }
    if(vy > 0) {
        if(ty >= sy) t21 = ty - sy, t22 = t21 + 2 * (m - ty);
        else t21 = sy - ty + 2 * (m - sy), t22 = t21 + 2 * ty;
    } else {
        if(ty <= sy) t21 = sy - ty, t22 = t21 + 2 * ty;
        else t21 = ty - sy + 2 * sy, t22 = t21 + 2 * (m - ty);
    }
    LL tim = INF;
    chkmin(tim, gao(2 * n, -2 * m, t11, t21));
    chkmin(tim, gao(2 * n, -2 * m, t11, t22));
    chkmin(tim, gao(2 * n, -2 * m, t12, t21));
    chkmin(tim, gao(2 * n, -2 * m, t12, t22));
    return tim;
}

void print(int who) {
    if(who == 0) cout << "0 0" << "
";
    else if(who == 1) cout << n << " " << "0
";
    else if(who == 2) cout << "0 " << m << "
";
    else if(who == 3) cout << n << " " << m << "
";
    else cout << "-1" << "
";
    exit(0);
}

int main() {
    cin >> n >> m >> sx >> sy >> vx >> vy;
    if(!vx) {
        if(sx == 0 && vy == 1) print(2);
        else if(sx == 0 && vy == -1) print(0);
        else if(sx == n && vy == 1) print(3);
        else if(sx == n && vy == -1) print(1);
        else print(-1);
    } else if(!vy) {
        if(sy == 0 && vx == 1) print(1);
        else if(sy == 0 && vx == -1) print(0);
        else if(sy == m && vx == 1) print(3);
        else if(sy == m && vx == -1) print(2);
        else print(-1);
    } else {
        LL tim = INF, who = -1;
        if(chkmin(tim, calc(sx, sy, vx, vy, 0, 0))) who = 0;
        if(chkmin(tim, calc(sx, sy, vx, vy, n, 0))) who = 1;
        if(chkmin(tim, calc(sx, sy, vx, vy, 0, m))) who = 2;
        if(chkmin(tim, calc(sx, sy, vx, vy, n, m))) who = 3;
        print(who);
    }
    return 0;
}

/*
*/
原文地址:https://www.cnblogs.com/CJLHY/p/10716404.html