zoukankan      html  css  js  c++  java
  • CF982E Billiard

    Solution

    将图经过小学就学了的反转转化成一条斜率为 (1) 的直线,那么有解就是经过了 (a)(n) 的同时经过了 (b)(m) ,又因为起点 (S(x,y)) 也经过这条直线,所以 (y) 轴交点为 ((0,y-x))

    然后就可得到:

    [an+(y-x)=bmRightarrow an-bm=x-yRightarrow an+b(-m)=x-y ]

    用扩展欧几里得求解完,再 (\%) 出个最小值即可。

    代码

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    
    using namespace std;
    int n,m,x,y,vx,vy;
    int rex,rey;
    
    inline int read(){
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
        return x*f;
    }
    
    ll exgcd(ll a,ll b,ll &x1, ll &y1){
        if(!b){
            x1=1;
            y1=0;
            return a;
        }
        ll ans=exgcd(b,a%b,x1,y1);
        ll t=x1;
        x1=y1;
        y1=t-a/b*y1;
        return ans;
    }
    
    int main(){
        n=read();m=read();x=read();y=read();vx=read();vy=read();
        //判断平行情况
        if(vx==0){
            if(x==0||x==n){
                if(vy==1) printf("%d %d
    ",x,m);
                else printf("%d %d
    ",x,0);
            }
            else puts("-1");
            return 0;
        }
        if(vy==0){
            if(y==0||y==m){
                if(vx==1) printf("%d %d
    ",n,y);
                else printf("%d %d
    ",0,y);
            }
            else puts("-1");
            return 0;
        }
        if(vx==-1) rex=1,x=n-x;
        if(vy==-1) rey=1,y=m-y;
        //这里就是将速度反转过来了
        ll a,b,gcd;
        gcd=exgcd(n,m,a,b);
        if((x-y)%gcd){//判断无解
            puts("-1");return 0;
        }
        a*=(x-y)/gcd,b*=(x-y)/gcd;//解出来的真正的a,b
        int n1=n/gcd,m1=m/gcd;
        ll a1=(a%m1+m1-1)%m1+1,b1=-((x-y)-a1*n)/m,ansx=n,ansy=m;//最小解
        if(a1%2==0) ansx=n-ansx;//经过偶数个n,此时应该是0
        if(b1%2==0) ansy=m-ansy;//经过偶数个m,此时应该是0
        if(rex) ansx=n-ansx;//反转
        if(rey) ansy=m-ansy;//反转
        printf("%lld %lld
    ",ansx,ansy);
        return 0;
    }
    
  • 相关阅读:
    【洛谷P1948】[USACO08JAN]电话线
    【洛谷P1967】[NOIP2013]货车运输
    【题解】洛谷P2926 [USACO08DEC]拍头Patting Heads
    【题解】洛谷P1495 曹冲养猪 (中国剩余定理)
    【题解】POJ1845 Sumdiv(乘法逆元+约数和)
    【题解】P1516 青蛙的约会(Exgcd)
    【数论】同余问题
    DP Cleaning Up 打扫卫生
    set+链表 【POJ Challenge】生日礼物
    并查集 [Scoi2010]游戏
  • 原文地址:https://www.cnblogs.com/jasony/p/13733790.html
Copyright © 2011-2022 走看看