首页 > 其他分享 >【poj1061】青蛙的约会(扩展欧几里得)

【poj1061】青蛙的约会(扩展欧几里得)

时间:2022-10-29 11:36:35浏览次数:56  
标签:poj1061 frac gcd operation 欧几里得 约会 times div ll

不妨设青蛙A的出发点坐标是\(m1\),青蛙B的出发点坐标是\(n1\)。青蛙A一次能跳\(m\)米,青蛙B一次能跳\(n\)米,跳一圈长\(l\)米,设青蛙A、B跳了\(x\)次。

那么题目要求的是满足下面这个柿子最小\(x\)正整数解:

\[(m-n)\times x\equiv m1-n1\pmod{l} \]

不妨把这个不定方程变形一下:

\[(m-n)\times x+l\times y=m1-n1 \]

看到这个形式,就想到用扩展欧几里得来求解。

不妨设\(a=m-n,b=l,c=m1-n1\)。

那么原方程就是:

\[a\times x+b\times y=c \]

然后我们知道一个性质:

若\(a\times x+b\times y=c\)有解,则满足\(gcd(a,b)|c\)。

所以说我们先判断方程是否有解,若无解就输出\(\mathbf{Impossible}\)。

然后如果有解,我们就先用扩展欧几里得求出\(a\times x+b\times y=gcd(a,b)\)的一组解。

然后我们对这个方程左右两边同时乘上\(c\div gcd(a,b)\)。

那么有:

\(a\times(c\div gcd(a,b))\times x+b\times(c\div gcd(a,b))\times y=c\)

为了方便起见,我们这里令\(p=a\times(c\div gcd(a,b))\),\(q=b\times(c\div gcd(a,b))\)。

这时,我们就可以求出满足下列方程的一组特解:

\(p\times x+q\times y=c\)

此时,我们发现\(x\)可以任意变为\((x+k\times \frac{q}{gcd(p,q)})\),且总有对应的一个整数解\(y\)使得原方程依旧成立,因为:

若\(p\times x+q\times y=c\)成立,则必有\(p\times (x+\frac{q}{gcd(p,q)})+q\times (y-\frac{p}{gcd(p,q)})=c\) 成立。

(为什么一定要除\(gcd(p,q)\)?因为在电脑中会向下取整,而且我们要使得\(\frac{q}{gcd(p,q)}\)尽量小,这样才能找到更多的\(x\)解)。

所以令\(g=\frac{q}{gcd(p,q)}\),即:

\[g=\frac{q}{gcd(p,q)}=\frac{b\times(c\div gcd(a,b))}{gcd(a\times(c\div gcd(a,b)),b\times(c\div gcd(a,b)))}=\frac{q}{gcd(a,b)} \]

那么\(x\)的最小正整数解为:

\[((x \bmod g)+g)\bmod g \]

那么我们就可以输出答案了。

代码流程梳理一下:

flowchat st=>start: 开始 e=>end: 结束 op=>operation: 求出gcd(a,b) op2=>operation: 输出"Impossible" op3=>operation: 求出exgcd(a,b) op4=>operation: x*=c/gcd(a,b),y*=c/gcd(a,b) op5=>operation: 求出g op6=>operation: 求出x的最小正整数解,输出 cond=>condition: gcd(a,b)是否整除c? st->op->cond op3->op4->op5->op6->e cond(yes)->op3 cond(no)->op2

最后代码如下:

#include<bits/stdc++.h>
 
#define ll long long
 
using namespace std;
 
ll m1,n1,m,n,l;
 
ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(!b)
    {
        x=1ll,y=0ll;
        return a;
    }
    ll ans=exgcd(b,a%b,x,y);
    ll xx=x;
    x=y;
    y=xx-(a/b)*y;
    return ans;
}
 
int main()
{
    while(~scanf("%lld%lld%lld%lld%lld",&m1,&n1,&m,&n,&l))
    {
        if(n<m)
        {
            swap(n,m);
            swap(n1,m1);
        }
        ll a=n-m,b=l,c=m1-n1,x,y;
        ll t=exgcd(a,b,x,y);
        if(c%t)
        {
            puts("Impossible");
            continue;
        }
        c/=t;
        x*=c;
        ll mod=b/t;
        x=(x%mod+mod)%mod;
        printf("%lld\n",x);
    }
    return 0;
}

标签:poj1061,frac,gcd,operation,欧几里得,约会,times,div,ll
From: https://www.cnblogs.com/ez-lcw/p/16838356.html

相关文章

  • 使用parseFloat()生成随机数的时候进行修约会出现“-0”
    今天遇到了个很奇怪的坑 使用parseFloat()生成随机数的时候进行修约会出现“-0”这个字符串记得parseFloat()是返回的浮点数来着,最开始以为是精度的问题后来调试的时......
  • 机器学习实战:knn海伦约会
    importnumpyasnpimportpandasaspdimportmatplotlib.pyplotaspltimportcopydefautoNorm(x):"""最大值最小值归一化:paramx:需要归一化的特征向量......
  • 1014 福尔摩斯的约会(JAVA)
    大侦探福尔摩斯接到一张奇怪的字条:我们约会吧!3485djDkxh4hhGE2984akDfkkkkggEdsbs&hgsfdkd&Hyscvnm大侦探很快就明白了,字条上奇怪的乱码实际上就是约会的时间​​星期四......
  • 1014 福尔摩斯的约会
     题目: 大侦探福尔摩斯接到一张奇怪的字条:我们约会吧!3485djDkxh4hhGE2984akDfkkkkggEdsbs&hgsfdkd&Hyscvnm 大侦探很快就明白了,字条上奇怪的乱码实际上就......
  • AcWing 算法提高课 拓展欧几里得算法 同余
    拓展欧几里得算法:1、模板:https://www.cnblogs.com/ydUESTC/p/16676229.html2、原理: 3、应用:拓展欧几里得算法解线性同余方程:  4、例题:(1)线性同余方程:https://w......
  • PAT (Basic Level) Practice 1014 福尔摩斯的约会 分数 20
    大侦探福尔摩斯接到一张奇怪的字条:我们约会吧!3485djDkxh4hhGE2984akDfkkkkggEdsbs&hgsfdkd&Hyscvnm 大侦探很快就明白了,字条上奇怪的乱码实际上就是约会的......
  • 类欧几里得,以及ARC111E和ARC123E
    例题https://atcoder.jp/contests/practice2/tasks/practice2_c在\(O(\log(n+m+k+b))\)的时间复杂度求:\[\sum_{i=0}^{n-1}\lfloor{\frac{ki+b}{m}}\rfloor\]其中\(n,......
  • 扩展欧几里得
    考虑问题求\(\ax\equiv1\pmod{b}\)的最小整数解,其中\(2\leqslanta,b\leqslant2000000000\)\(\\\)数据范围这么大我们肯定不能枚举,考虑别的方法。\(\\\)发现问题......
  • 扩展欧几里得算法
    引入:欧几里得算法欧几里得算法其实就是辗转相除法,用来求2个数的最大公因数。复杂度:\(O(\logn)\)\(code\)intgcd(inta,intb){return!b?a:gcd(b,a%b);}......
  • 数论——扩展欧几里得【未完结】
    No.1 前置知识欧几里得算法(辗转相除法)裴蜀定理No.2算法,证明及函数扩展欧几里得算法用来解决这样一个问题:给定两个非零的整数\(a\)和\(b\),求一组整数解\((......