zoukankan      html  css  js  c++  java
  • POJ 1061青蛙的约会。求解(x+mT)%L=(y+nT)%L的最小步数T。

    因为是同余,所以就是(x+mT)%L-(y+nT)%L=0。可以写成(x-y+(m-n)T)%L=0。就是这个数是L的倍数啦。那么我可以这样x-y+(m-n)T + Ls = 0。就可以了,s可正可负,就能满足条件。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    LL gcd(LL n,LL m)
    {
        if (n%m==0) return m;
        else return gcd(m,n%m);
    }
    LL exgcd (LL a,LL mod,LL &x,LL &y)
    {
        //求解a关于mod的逆元
        if (mod==0)
        {
            x=1;y=0;
            return a;//保留基本功能,返回最大公约数
        }
        LL g=exgcd(mod,a%mod,x,y);
        LL t=x;    //这里根据mod==0  return回来后,
        x=y;    //x,y是最新的值x2,y2,改变一下,这样赋值就是为了x1=y2
        y=t-(a/mod)*y;    // y1=x2(变成了t)-[a/mod]y2;
        return g;            //保留基本功能,返回最大公约数
    }
    LL get_min_number (LL a,LL b,LL c,LL &x,LL &y)
    {
        //得到a*x+b*y=c的最小整数解
        LL abGCD = gcd(a,b);//系统gcd
        if (c%abGCD != 0) return -1;//无解
        a /= abGCD; b /= abGCD; c /= abGCD;
        LL tx,ty;
        exgcd(a,b,tx,ty); //先得到a*x+b*y=1的解,注意这个时候gcd(a,b)=1
        x = tx*c;   y = c*ty;//任意一个解,就是因为你求的是a*x+b*y=1的解,但是我们需要的是a*x+b*y=c的解,所以同时乘上c
        //然后这个方程的解就是x0=tx*c+b*k,y0=ty*c-a*k。这里的a和b约简了的。k是{-1,-2,0,1,2}等
        LL temp_x = x;
        x %= b; if (x<=0) x += b;//最小解
        LL k = (temp_x-x)/b;
        y += k*a;
        return 1;//1代表可以
    }
    void work ()
    {
        LL x,y,n,m,L;
        cin>>x>>y>>m>>n>>L;
        LL a=m-n;
        LL b=L;
        LL c=y-x;
        LL tx,ty;
        LL t = get_min_number(a,b,c,tx,ty);
        if (t==-1)
        {
            cout<<"Impossible"<<endl;
            return ;
        }
        if (b<0) b=-b;
        while(tx<0) tx += b;
        cout<<tx<<endl;
        return ;
    
    }
    int main()
    {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        work();
        return 0;
    }
    View Code

    ★、求解方程ax+by=c的最小整数解 (a或者b是负数的话,直接放进去也没问题)

    首先就是如果要求解ax+by=c的话,用exgcd可以求到ax+by=1的x,y。那么我们首先把a和b约成互质的(除以gcd(a,b)即可),求到Ax+By=1的x和y后,但是我们要的是Ax+By=C的解,所以同时乘上C,这里的大写的字母是代表约去gcd(a,b)后的方程。然后这个方程的解就是x0=tx*C+B*k。y0=ty*C-A*k。k是{-1,-2,0,1,2}等。

    int get_min_number (int a,int b,int c,int &x,int &y)    //得到a*x+b*y=c的最小整数解

    {

        int abGCD = gcd(a,b);

        if (c%abGCD != 0) return -1;//无解

        a /= abGCD; b /= abGCD; c /= abGCD;

        int tx,ty;

        exgcd(a,b,tx,ty); //先得到a*x+b*y=1的解,注意这个时候gcd(a,b)=1

        x = tx*c;   y = c*ty; //同时乘上c,c是约简了的

        int temp_x = x;

        x %= b; if (x<=0) x += b;//最小解

        int k = (temp_x-x)/b;

        y += k*a;

        return 1;//1代表可以

    }

    若要得到最小的正整数解。注意这里要先判定他们是否存在解,不然TLE

    int bb=abs(b/gcd(a,b));

    int aa=abs(a/gcd(a,b));

    while(x<0) x += bb;

    while(x*a+b*y!=c) y += aa;

  • 相关阅读:
    Diffusion Particle Resolver
    GPU Jacobi Iterator
    Remark for ColorSpectrum Rendering
    关于Windows的命令行多语言输出
    DPR Sphere in Cloud
    看到一篇有意思的东西,记录一下
    GFS的系统架构
    jsp实现树状结构
    工作笔记
    批量删除
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/5768990.html
Copyright © 2011-2022 走看看