蓝桥杯之初等数论(二)

上一篇:蓝桥杯之初等数论(一)讲了两种知识点,即素数和合数的判断,最大公约数和最小公倍数的判断,接下来,我继续讲解有关初等数论的有关知识点。

什么是同余定理:

同余定理,也称为模运算定理或同余式定理,是数论中的一个重要概念。它主要涉及到整数之间的某种等价关系,即两个整数除以同一个正整数,如果所得的余数相同,则称这两个整数对于该正整数同余。同余关系是一种等价关系,满足反身性、对称性和传递性。

同余定理在数学、计算机科学和密码学等领域都有广泛的应用。例如,在密码学中,同余定理常被用于构建各种加密算法和协议,确保信息的安全传输。在计算机科学中,同余定理也用于优化算法和提高计算效率。

具体来说,如果整数a和b除以正整数m的余数相同,那么我们就说a和b对模m同余,记作a≡b(mod m)。这里的"mod"表示取模运算,即求一个数除以另一个数的余数。同余定理在实际应用中可以帮助我们简化复杂的计算问题,通过将问题转化为模运算的形式,从而更容易找到解决方案。

下面让我们以一个例子来熟悉这个定理:

假设我们要找出所有小于20的正整数,这些整数除以3的余数等于2。

根据同余定理,我们可以表示为:x ≡ 2 (mod 3),其中x是我们要找的数。

现在,我们开始尝试小于20的每个正整数x,并检查它是否满足上述同余关系:

  1. 当x=1时,1除以3的余数是1,不等于2,所以不满足。
  2. 当x=2时,2除以3的余数是2,满足条件。
  3. 当x=3时,3除以3的余数是0,不等于2,所以不满足。
  4. 当x=4时,4除以3的余数是1,不等于2,所以不满足。
  5. 当x=5时,5除以3的余数是2,满足条件。

以此类推,我们继续检查直到x=20。通过这个过程,我们可以找出所有满足条件的x值,即那些除以3余数为2的数。在这个例子中,这些数是2, 5, 8, 11, 14, 17。

在Java中,实现同余定理的验证和求解相对简单。以下是一个简单的Java程序,用于查找小于给定值(例如20)的所有整数,这些整数满足除以3余数为2的条件。

java 复制代码
public class CongruenceExample {  
    public static void main(String[] args) {  
        int modulus = 3; // 模数  
        int remainder = 2; // 余数  
        int limit = 20; // 限制查找的整数小于这个值  
  
        // 查找并打印所有小于limit且满足x mod modulus = remainder的整数x  
        for (int x = 1; x < limit; x++) {  
            if (x % modulus == remainder) {  
                System.out.println(x + " ≡ " + remainder + " (mod " + modulus + ")");  
            }  
        }  
    }  
}

当你运行这个程序时,它会输出所有小于20且满足x ≡ 2 (mod 3)的整数。

如果你想要解一个同余方程,比如ax ≡ b (mod m),并且你知道am是互质的(即它们的最大公约数为1),你可以使用扩展欧几里得算法来找到x的一个解。下面是一个使用扩展欧几里得算法来解同余方程的Java实现示例

java 复制代码
public class CongruenceSolver {  
    public static void main(String[] args) {  
        int a = 2; // 方程的系数a  
        int b = 5; // 方程的余数b  
        int m = 3; // 模数m  
  
        // 求解同余方程 ax ≡ b (mod m)  
        int solution = solveCongruence(a, b, m);  
        if (solution != -1) {  
            System.out.println("同余方程的一个解是:x = " + solution);  
        } else {  
            System.out.println("同余方程无解");  
        }  
    }  
  
    // 使用扩展欧几里得算法求解同余方程 ax ≡ b (mod m)  
    public static int solveCongruence(int a, int b, int m) {  
        // 扩展欧几里得算法求解 ax + my = gcd(a, m)  
        int[] result = extendedGcd(a, m);  
        int gcd = result[0];  
  
        // 检查是否有解  
        if (b % gcd != 0) {  
            return -1; // 无解,因为b不是gcd的倍数  
        }  
  
        // 计算x的值  
        int x = (b / gcd * result[1]) % m;  
        if (x < 0) {  
            x += m; // 保证解是非负的  
        }  
        return x;  
    }  
  
    // 扩展欧几里得算法求解 ax + by = gcd(a, b)  
    public static int[] extendedGcd(int a, int b) {  
        if (b == 0) {  
            return new int[]{a, 1, 0}; // gcd, x, y  
        }  
        int[] vals = extendedGcd(b, a % b);  
        int gcd = vals[0];  
        int x = vals[2];  
        int y = vals[1] - (a / b) * vals[2];  
        return new int[]{gcd, x, y};  
    }  
}

首先,让我们回顾一下同余方程ax ≡ b (mod m)。这个方程意味着存在一个整数x,使得ax除以m的余数是b。这样的x可能有多个解,或者可能无解,这取决于abm的具体值。

现在,让我们逐步分析CongruenceSolver类中的代码:

  1. 主方法 (main) :
    • 初始化变量abm
    • 调用solveCongruence方法求解同余方程,并打印结果。
  2. 求解同余方程的方法 (solveCongruence) :
    • 使用extendedGcd方法求解ax + my = gcd(a, m)。这里的gcd(a, m)表示am的最大公约数。
    • 检查b是否是gcd(a, m)的倍数。如果不是,则方程无解,返回-1。
    • 如果有解,则根据扩展欧几里得算法的结果计算x的值,并返回它。
  3. 扩展欧几里得算法 (extendedGcd) :
    • 这是一个递归方法,用于求解ax + by = gcd(a, b)的整数解xy
    • b为0时,gcd(a, b)就是a,此时x为1,y为0。
    • 否则,递归调用extendedGcd(b, a % b),并根据递归结果计算xy的值。

现在,让我们逐步解释扩展欧几里得算法如何工作:

扩展欧几里得算法是基于欧几里得算法(用于计算最大公约数)的扩展。它不仅能找到两个数的最大公约数,还能找到使得ax + by = gcd(a, b)成立的整数xy

递归的基础情况是当b为0时,此时gcd(a, 0)就是a,且x为1,y为0满足方程。

对于递归的其他情况,我们利用欧几里得算法的一个性质:gcd(a, b) = gcd(b, a % b)。因此,我们可以递归地求解bx' + (a % b)y' = gcd(b, a % b),其中x'y'是新的未知数。一旦我们得到了x'y'的值,我们就可以利用它们来计算xy的值。

具体来说,我们有:

复制代码

复制代码

|---|------------------------------------------------------------------------|
| | bx' + (a % b)y' = gcd(b, a % b) |
| | bx' + (a - (a / b) * b)y' = gcd(a, b) // 因为 a % b = a - (a / b) * b |
| | ax - by = gcd(a, b) // 这是我们要找的方程 |

通过比较上述两个方程,我们可以解出xy

复制代码

复制代码

|---|-------------------------|
| | x = y' |
| | y = x' - (a / b) * y' |

这样,我们就可以使用递归的结果来计算xy的值。

solveCongruence方法中,我们利用扩展欧几里得算法找到x的一个值,该值满足ax + my = gcd(a, m)。然后,我们通过乘以b / gcd(a, m)并取模m来找到满足ax ≡ b (mod m)x的值。

相关推荐
LYFlied6 小时前
【每日算法】LeetCode 416. 分割等和子集(动态规划)
数据结构·算法·leetcode·职场和发展·动态规划
坚持学习前端日记7 小时前
软件开发完整流程详解
学习·程序人生·职场和发展·创业创新
张老师Plus10 小时前
依依东望,望的是时间
经验分享·程序人生·面试·职场和发展·跳槽
坚持学习前端日记13 小时前
2025年的个人和学习年度总结以及未来期望
java·学习·程序人生·职场和发展·创业创新
爱敲代码的边芙17 小时前
秋招面试准备(后端开发)
面试·职场和发展
坚持学习前端日记17 小时前
个人运营小网站的最佳策略
java·学习·程序人生·职场和发展·创业创新
大布布将军18 小时前
☁️ 自动化交付:CI/CD 流程与云端部署
运维·前端·程序人生·ci/cd·职场和发展·node.js·自动化
leoufung19 小时前
LeetCode 322. Coin Change:从错误思路到正确一维 DP
算法·leetcode·职场和发展
Swift社区19 小时前
LeetCode 463 - 岛屿的周长
算法·leetcode·职场和发展