• 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;
    }
    
    /*
    */
  • 相关阅读:
    PHP分页类
    phpexcel 控制导出数据内容和行数
    phpexcel 导入 和 导出
    PHP无限极分类
    php 对查询结果集进行排序
    php 删除文件夹及文件夹内文件函数
    php 字符串截取函数
    php 获取用户登录的ip
    js layer页面层加载新网站
    分享到qq
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10716404.html
Copyright © 2020-2023  润新知