HRBU_2022.10.15

青蛙的约会

算法:exgcd



int exGcd(int a, int b, int &x, int &y)   //x和y使用引用
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    int g = exGcd(b, a%b, x, y);    //递归计算exGcd(b,a%b)
    int temp = x;             //存放x的值
    x = y;
    y = temp - (a/b)*y;       //更新y = x(old) - a/b*y(old)
    return g;                 //g是gcd
}


void sol()
{
    int x,m; //A 位置 步长
    int y,n; //B 位置 步长
    int L;
    cin>>x>>y>>m>>n;
    cin>>L; // mod L

    /*
        跳k次
        (x+k*m)%L=(y+k*n)%L
        ((x-y)+(m-n)*k)%L=0
        (x-y)+(m-n)*k=kk*L
        kk*L-k*mn=xy


    */
    int xy=x-y;
    int mn=n-m;
    //        注意:
    //       GCD 得同号
    if(mn<0)
    {
        xy*=-1;
        mn*=-1;
    }
    int k,kk;
    int gcd=exGcd(mn,L,k,kk);
    if(xy%gcd)
    {
        cout<<"Impossible\n";
    }
    else
    {
        cout<<(k*(xy/gcd)%(L/gcd)+(L/gcd))%(L/gcd)<<endl;
    }
    return ;
}

根据斐蜀定理如果代码注释中公式成立则,最右边必然是gcd的倍数

以此可求是否可能相遇

思想用拓展欧几里得,等号最右边是gcd时求出此时条件下的步数,以此还原最初公式的步数

        证明:

        gcd*(xy/gcd)=xy

        最终还原

        而输出项的%(L/gcd)的这个是因为最初公式是模L,过程中/gcd了

        所以最终要%(L/gcd)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

活在当下 北乔

不爱多bb,朴实一句话:感谢您

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值