zoukankan      html  css  js  c++  java
  • 《数论练习》

    P1516 青蛙的约会(洛谷)

    题意:在一个循环坐标轴上,有两个初始坐标为x,y的点,每个人一次跳m,n步,求解是否可以相遇,如果可以求出最小步数。

    假设跳了k步后两点相遇。则有

    x+k*m - (y+k*n) = T * L(T为常数,即表示为L的常数倍,因为是循环坐标轴)

    转化为 TL+(n-m)*k = x-y;

    设 a = L,b = n-m,x = t,y = k,c = x-y;

    那么式子转化为  ax+by = c;

    显然是扩展欧几里得求解。

    扩展欧几里得求得 ax0+by0 = gcd(a,b)-+
    两边同时乘以c / gcd(a,b) (一定是整除,因为c是gcd(a,b)的倍数)
    a*xo*c / gcd(a,b) + b*yo*c / gcd(a,b).
    此时
    x = xo*c / gcd(a,b);
    y = yo*c / gcd(a,b)
    x,y即为ax + by = c的一组特解。
    关于求解最小正整数解的求法。
    x = (x % (b/gcd(a,b)+gcd(a,b) ) % gcd(a,b)
    y = (y % (a/gcd(a,b)+gcd(a,b) ) % gcd(a,b)
    由定式推得(证明略)
    需要注意的是,gcd只对非负整数有效。

    b可能是负数,此时需要对等式两边取反,但是a不用取反,因为可以将x看成-T来实现取反效果。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef long double ld;
    typedef pair<LL,int> pii;
    const int N = 1e3+5;
    const int M = 1e6+5;
    const LL Mod = 1e9+7;
    #define rg register
    #define pi acos(-1)
    #define INF 1e9
    #define INM INT_MIN
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline LL read()
    {
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
    LL xx,yy,n,m,L;
    LL exgcd(LL a,LL b,LL &x,LL &y)
    {
        if(b == 0)
        {
            x = 1,y = 0;
            return a;
        }
        LL t = exgcd(b,a%b,y,x);
        y -= a/b*x;
        return t;
    }
    int main() 
    {
        xx = read(),yy = read(),m = read(),n = read(),L = read();
        LL a = L,b = n-m,c = xx-yy,x,y;
        if(b < 0) b = -b,c = -c;
        LL gcd = exgcd(a,b,x,y);
        if(c%gcd != 0) printf("Impossible\n");
        else
        {
            LL ma = c/gcd*y;
            LL ans = (ma % (a/gcd) + (a/gcd))%(a/gcd);
            printf("%lld\n",ans);
        }
       // system("pause");
        return 0;
    }
    View Code

    The Balance(POJ 2142)

    题意:给定两个种类砝码,和一个要称量的物体。计算是否能够通过天平测量出这个物品,如果能,求最少需要的砝码总和。

    设a种砝码x个,b种砝码y个。称量的物体种类为c。

    即满足a*x + b*y = c.

    注意的是砝码可以放左和右。那么这里定义放左为正,右为负,所以x,y可能为负。

    这里求的即为abs(x) + abs(y)的最小值。

    可以证明,肯定是满足一边为最小正整数个时,总和最小。

    那么扩展欧几里得可以计算出x为最小正整数时,和y为最小正整数时的情况,求最小的情况即可。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef long double ld;
    typedef pair<LL,int> pii;
    const int N = 1e5+5;
    const int M = 1e6+5;
    const LL Mod = 1e9+7;
    #define rg register
    #define pi acos(-1)
    #define INF 1e9
    #define INM INT_MIN
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline LL read()
    {
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
    int exgcd(int a,int b,int &x,int &y)
    {
        if(b == 0)
        {
            x = 1,y = 0;
            return a;
        }
        int t = exgcd(b,a%b,y,x);
        y -= a/b*x;
        return t;
    }
    int main()
    {
        int a,b,d,x,y;
        while((a = read(),b = read(),d = read()),a || b || d)
        {
            int gcd = exgcd(a,b,x,y);
            if(d % gcd != 0) printf("no solution\n");
            else
            {
                int t1 = x*d/gcd,t2 = y*d/gcd;
                int ma1 = (t1%(b/gcd)+(b/gcd))%(b/gcd);//最小正整数x
                int ma2 = (t2%(a/gcd)+(a/gcd))%(a/gcd);//最小正整数y
                int ma3 = abs((d-a*ma1)/b);//注意取绝对值,因为可能是放在不同边
                int ma4 = abs((d-b*ma2)/a);//同理
                if(ma1+ma3 < ma2+ma4) printf("%d %d\n",ma1,ma3);
                else printf("%d %d\n",ma4,ma2);
            }
        }
        system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    angular入门学习文档之一
    将SDL程序变成网页(使用emscripten)
    Nim使用OpenGL
    C++移动操作,RVO和NRVO
    从零开始制作一个粒子系统
    cocos2d-x学习之路(一)——安装cocos2d-x
    堆排序
    开发zeroc ice应用入门(java开发ice应用,python开发ice应用,java与python结合开发ice服务)
    eclipse自动提示设置以及问题:去除变量自动提示(图文详解)
    ubuntu安装新版QQ
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/13424464.html
Copyright © 2011-2022 走看看