zoukankan      html  css  js  c++  java
  • 方程的解题解和扩欧的一些总结

    题目描述

    给出一个二元一次方程ax+by=c,其中x、y是未知数,求它的正整数解的数量。

    输入输出格式

    输入格式:

    第一行一个整数T,表示有T组数据。接下来T行,每行3个整数a、b、c。

    输出格式:

    输出T行,每行一个数,表示方程解的数量。如果正整数解的数量比65535还多输出“ZenMeZheMeDuo”。

    题解

    这个题一看就要先用扩展欧几里得求出一组x最小的整数解然后再计算出所有的解。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    long long Exgcd(long long a, long long b, long long & x, long long & y)
        {
            if(b == 0)
                {
                    x = 1, y = 0;
                    return a;
                }
            int q = Exgcd(b, a % b, y, x);
            y -= x * (a / b);
            return q; 
        }
    
    long long Get_ans_num(long long  a, long long b, long long c, long long &x, long long &y)
        {
            const int maxnum = 70000;
            long long fa = 0, fb = 0;
            if(a == 0 && b == 0)
                {
                    if(c == 0)    return maxnum;
                    else return 0;
                }
            if(a == 0)
                {
                    if(c == 0)    return maxnum;
                    if(c % b == 0 && c /b > 0)    return maxnum;
                    return 0;
                }
            if(b == 0)
                {
                    if(c == 0)    return maxnum;
                    if(c % a == 0 && c / a > 0)    return maxnum;
                    return 0;
                }
            if(c < 0)    a = -a, b = -b, c = -c;
            if(a < 0)    a = -a, fa = 1;
            if(b < 0)    b = -b, fb = 1;
            long long gcd = Exgcd(a, b, x, y);
            if(c % gcd != 0) return 0;
            long long t = c / gcd;
            x = x * t, y = y * t;
            a = a / gcd, b = b / gcd, c = t;        
            if(fa)    a = -a, x = -x;
            if(fb)    b = -b, y = -y;
            if(a < 0)    a = -a, b = -b, c = -c;
            if(a * b < 0)    return maxnum;
            x = x % b;
            for(;x <= 0;) x += b;
            y = (c - a * x) / b;
            if(y < 0)    return 0;
            long long miny = y % a;
            for(;miny <= 0;)    miny += a;
            if(miny > y)    return 0;
            return (y - miny) / a + 1;
        }
    
    int main()
    {
        //freopen("fuction.in", "r", stdin);
        //freopen("fuction.out", "w", stdout);
        long long T, a, b, c, ans, x, y;
        scanf("%lld", &T);
        for(int i = 1; i <= T; ++ i)
            {
                scanf("%lld%lld%lld", &a, &b, &c);
                ans = Get_ans_num(a, b, c, x, y);
                if(ans <= 65535) printf("%lld
    ", ans);
                else    printf("ZenMeZheMeDuo
    ");
            }
    }


    关于扩展欧几里得的总结

    1. 扩欧与方程的通解

      扩展欧几里得是用于求解方程 ax + by = gcd(a,b)的解的(要求a,b非负)。对于方程ax+by=gcd(a,b),知道一组特解x0,y0我们一定能够求出它的通解:

        

      将其推广的话对于方程ax+by=c,我们首先要解的方程是ax+by=gcd(a,b)解为x0’,y0'

      若c|gcd(a,b),则令t=c/gcd(a,b),对于等式ax0‘+by0‘=gcd(a,b)两边同时乘以t就有等式a(tx0')+b(ty0')=gcd(a,b)*t=c,所以原方程的一组解就是x0=tx0',y0=ty0',而在这种情况下,我们能够得到它们的通解:

      

    2.在二元一次方程组整数解中的一些特殊情况(ax+by=c)

      • 若a==0且b==0,若有c==0,则有无数组解,但若c!=0则无解。
      • 当a*b>0时整数解的组数有可能是有限的。
      • 当a==0时若有c%b==0则有无数组解(x可取任意整数,y=(c/b)),当y>0时有无数组正整数解;b==0时亦然。

      3.在用扩欧解方程时,若有负数,可通过方程式变形来处理

  • 相关阅读:
    python实现简单爬虫功能
    python re group()
    [转载]python 详解re模块
    Python 异常处理
    Python中os和shutil模块实用方法集锦
    Python中os和shutil模块实用方法集锦
    关于selenium IDE找不到元素
    关于selenium IDE找不到元素
    关于selenium IDE找不到元素
    js模拟点击事件实现代码
  • 原文地址:https://www.cnblogs.com/2020pengxiyue/p/9314237.html
Copyright © 2011-2022 走看看