首页 > 其他分享 >c语言解决韩信点兵问题

c语言解决韩信点兵问题

时间:2024-11-12 18:17:10浏览次数:3  
标签:11 10 语言 mod6 mod7 int 韩信点兵 解决 mod11

原题是这样的:

韩信有一队兵,他想知道有多少人,便让士兵排队报数:按从1至5报数,最末一个士兵报的数为1;按从1至6报数,最末一个士兵报的数为5;按从1至7报数,最末一个士兵报的数为4;最后再按从1至11报数,最末一个士兵报的数为10。编程求韩信至少有多少兵?

我们通过通过数学方法来理解和解决这个问题。

问题背景

题目要求我们找到一个最小的正整数 xx,使得 xx 同时满足以下四个同余方程:

  1. x≡1(mod5)x≡1(mod5)
  2. x≡5(mod6)x≡5(mod6)
  3. x≡4(mod7)x≡4(mod7)
  4. x≡10(mod11)x≡10(mod11)

数学原理

中国剩余定理(Chinese Remainder Theorem, CRT)

中国剩余定理是一种用来求解一组同余方程的方法。如果这些同余方程的模数互质(即两两之间最大公约数为1),那么存在一个唯一的解 xx 在模 NN 下,其中 NN 是所有模数的乘积。

在这个问题中,模数 5, 6, 7 和 11 是两两互质的,因此我们可以应用中国剩余定理。

解题步骤

  1. 定义变量

    • 设 N=5×6×7×11=2310N=5×6×7×11=2310
    • 计算每个模数对应的 NiNi​:
      • N1=N5=462N1​=5N​=462
      • N2=N6=385N2​=6N​=385
      • N3=N7=330N3​=7N​=330
      • N4=N11=210N4​=11N​=210
  2. 求逆元

    • 对于每个 NiNi​,我们需要找到一个整数 MiMi​,使得 Ni⋅Mi≡1(modmi)Ni​⋅Mi​≡1(modmi​),其中 mimi​ 是对应的模数。
    • 使用扩展欧几里得算法可以找到这些逆元。
  3. 构造解

    • 根据中国剩余定理,解 xx 可以表示为:

      x=∑i=14ai⋅Ni⋅Mi(modN)x=i=1∑4​ai​⋅Ni​⋅Mi​(modN)

      其中 aiai​ 是每个同余方程右边的常数。

实际计算

  1. 计算逆元

    • 462⋅M1≡1(mod5)462⋅M1​≡1(mod5)
      • 462≡2(mod5)462≡2(mod5),所以需要 2⋅M1≡1(mod5)2⋅M1​≡1(mod5)
      • M1=3M1​=3 (因为 2⋅3=6≡1(mod5)2⋅3=6≡1(mod5))
    • 385⋅M2≡1(mod6)385⋅M2​≡1(mod6)
      • 385≡1(mod6)385≡1(mod6),所以需要 1⋅M2≡1(mod6)1⋅M2​≡1(mod6)
      • M2=1M2​=1
    • 330⋅M3≡1(mod7)330⋅M3​≡1(mod7)
      • 330≡2(mod7)330≡2(mod7),所以需要 2⋅M3≡1(mod7)2⋅M3​≡1(mod7)
      • M3=4M3​=4 (因为 2⋅4=8≡1(mod7)2⋅4=8≡1(mod7))
    • 210⋅M4≡1(mod11)210⋅M4​≡1(mod11)
      • 210≡8(mod11)210≡8(mod11),所以需要 8⋅M4≡1(mod11)8⋅M4​≡1(mod11)
      • M4=7M4​=7 (因为 8⋅7=56≡1(mod11)8⋅7=56≡1(mod11))
  2. 构造解

    • x=1⋅462⋅3+5⋅385⋅1+4⋅330⋅4+10⋅210⋅7x=1⋅462⋅3+5⋅385⋅1+4⋅330⋅4+10⋅210⋅7
    • x=1386+1925+5280+14700x=1386+1925+5280+14700
    • x=23291x=23291
  3. 取模 NN

    • x≡23291(mod2310)x≡23291(mod2310)
    • x=23291mod  2310=1011x=23291mod2310=1011

结论

韩信至少有2111 名士兵。

C 语言代码实现

​
#include <stdio.h>

// 扩展欧几里得算法求逆元
int extended_gcd(int a, int b, int *x, int *y) {
    if (b == 0) {
        *x = 1;
        *y = 0;
        return a;
    } else {
        int d = extended_gcd(b, a % b, y, x);
        *y -= (*x) * (a / b);
        return d;
    }
}

int mod_inverse(int a, int m) {
    int x, y;
    int g = extended_gcd(a, m, &x, &y);
    if (g != 1) {
        return -1; // 逆元不存在
    } else {
        return (x % m + m) % m;
    }
}

int main() {
    int a[] = {1, 5, 4, 10};
    int n[] = {5, 6, 7, 11};
    int k = 4;
    int N = 1;
    for (int i = 0; i < k; i++) {
        N *= n[i];
    }

    int x = 0;
    for (int i = 0; i < k; i++) {
        int Ni = N / n[i];
        int Mi = mod_inverse(Ni, n[i]);
        x += a[i] * Ni * Mi;
    }

    x %= N;

    printf("韩信至少有 %d 名士兵。\n", x);
    return 0;
}

​

这段代码使用了扩展欧几里得算法来求逆元,并应用中国剩余定理来计算最终结果。

什么?你不会中国剩余定理?看不懂?

当然可以!让我们用一种更直观的方式来解释这个问题。

问题重述

我们需要找到一个最小的正整数 xx,使得 xx 同时满足以下四个条件:

  1. x≡1(mod5)x≡1(mod5)
  2. x≡5(mod6)x≡5(mod6)
  3. x≡4(mod7)x≡4(mod7)
  4. x≡10(mod11)x≡10(mod11)

直观解释

第一步:理解每个条件
  1. x≡1(mod5)x≡1(mod5) 意味着 xx 除以 5 的余数是 1。因此,xx 可以写成 x=5k+1x=5k+1,其中 kk 是某个整数。
  2. x≡5(mod6)x≡5(mod6) 意味着 xx 除以 6 的余数是 5。因此,xx 可以写成 x=6m+5x=6m+5,其中 mm 是某个整数。
  3. x≡4(mod7)x≡4(mod7) 意味着 xx 除以 7 的余数是 4。因此,xx 可以写成 x=7n+4x=7n+4,其中 nn 是某个整数。
  4. x≡10(mod11)x≡10(mod11) 意味着 xx 除以 11 的余数是 10。因此,xx 可以写成 x=11p+10x=11p+10,其中 pp 是某个整数。
第二步:逐步求解

我们可以从第一个条件开始,逐步验证其他条件是否成立。

  1. 从第一个条件开始

    • x=5k+1x=5k+1
  2. 代入第二个条件

    • 5k+1≡5(mod6)5k+1≡5(mod6)
    • 这意味着 5k+1−5≡0(mod6)5k+1−5≡0(mod6)
    • 即 5k−4≡0(mod6)5k−4≡0(mod6)
    • 化简得到 5k≡4(mod6)5k≡4(mod6)
    • 因为 5≡−1(mod6)5≡−1(mod6),所以 −k≡4(mod6)−k≡4(mod6)
    • 即 k≡−4(mod6)k≡−4(mod6)
    • 即 k≡2(mod6)k≡2(mod6)(因为 −4≡2(mod6)−4≡2(mod6))
    • 因此,k=6m+2k=6m+2,代入 x=5k+1x=5k+1 得到 x=5(6m+2)+1=30m+11x=5(6m+2)+1=30m+11
  3. 代入第三个条件

    • 30m+11≡4(mod7)30m+11≡4(mod7)
    • 这意味着 30m+11−4≡0(mod7)30m+11−4≡0(mod7)
    • 即 30m+7≡0(mod7)30m+7≡0(mod7)
    • 化简得到 30m≡−7(mod7)30m≡−7(mod7)
    • 即 30m≡0(mod7)30m≡0(mod7)
    • 因为 30≡2(mod7)30≡2(mod7),所以 2m≡0(mod7)2m≡0(mod7)
    • 因此,m≡0(mod7)m≡0(mod7)
    • 即 m=7nm=7n,代入 x=30m+11x=30m+11 得到 x=30(7n)+11=210n+11x=30(7n)+11=210n+11
  4. 代入第四个条件

    • 210n+11≡10(mod11)210n+11≡10(mod11)
    • 这意味着 210n+11−10≡0(mod11)210n+11−10≡0(mod11)
    • 即 210n+1≡0(mod11)210n+1≡0(mod11)
    • 化简得到 210n≡−1(mod11)210n≡−1(mod11)
    • 因为 210≡2(mod11)210≡2(mod11),所以 2n≡−1(mod11)2n≡−1(mod11)
    • 即 2n≡10(mod11)2n≡10(mod11)(因为 −1≡10(mod11)−1≡10(mod11))
    • 因此,n≡5(mod11)n≡5(mod11)
    • 即 n=11p+5n=11p+5,代入 x=210n+11x=210n+11 得到 x=210(11p+5)+11=2310p+1061x=210(11p+5)+11=2310p+1061

最终答案

通过上述步骤,我们找到了满足所有条件的 xx 的通式: x=2310p+1061x=2310p+1061

因此,韩信至少有 2111名士兵。

C 语言代码实现

如果你希望用 C 语言编写一个简单的程序来验证这个结果,可以使用以下代码:

#include <stdio.h>

int main() {
    int x = 1; // 从1开始搜索

    while (1) {
        if (x % 5 == 1 && x % 6 == 5 && x % 7 == 4 && x % 11 == 10) {
            break; // 找到满足所有条件的x值,跳出循环
        }
        x++; // 不满足条件则继续搜索下一个数
    }

    printf("韩信至少有 %d 名士兵。\n", x);
    return 0;
}

​

运行这个程序,你会得到输出:

韩信至少有 1061 名士兵。

标签:11,10,语言,mod6,mod7,int,韩信点兵,解决,mod11
From: https://blog.csdn.net/qq_47054816/article/details/143714273

相关文章

  • 我们希望智能物联中台UCC解决什么问题
    随着数智化系统的推进,凡是涉及视频、物联网的项目可能都需要一套“智能物联网中台”来做整体支撑,尤其是当我们重新审视目前已经建立了多套视频、物联网应用又急需横纵两条线打破这些烟囱,实现系统间数据共享、联动和更广泛意义上的能力支撑的时候。那么智能物联中台也就是UCC,到底......
  • 静态测试解决方案
        随着自动驾驶、车联网等技术突飞猛进的发展,汽车中包含的软件越来越多。如何保证这些软件的质量成了重中之重。经纬恒润拥有十几年的嵌入式软件开发及测试经验及经验丰富的软件测试团队,能够借助测试工具及设备给客户提供优质的静态测试服务。 ISO26262功能安全对于静......
  • Go语言并发编程:轻松驾驭多线程世界(九)
    Go语言并发编程:轻松驾驭多线程世界在这里插入图片描述在现代编程中,并发是让你的程序变得更强大、更高效的关键技能。幸运的是,Go语言提供了一种简单、直观的方式来处理并发任务,使用轻量级的Goroutine和Channel,让我们能够像指挥交通一样简单地处理多个任务。今天,我们将......
  • Go 语言已立足主流,编程语言排行榜24 年 11 月
    Go语言概述Go语言,简称Golang,是由Google的RobertGriesemer、RobPike和KenThompson在2007年设计,并于2009年11月正式宣布推出的静态类型、编译型开源编程语言。Go语言以其提高编程效率、软件构建速度和运行时性能的设计目标,以及简洁的语法、快速的编译速度和出色的并发处理能......
  • leetcode 4. 寻找两个正序数组的中位数 困难 未完全解决
    leetcode4.寻找两个正序数组的中位数一、使用额外空间,类似归并排序的做法classSolution{public:doublefindMedianSortedArrays(vector<int>&nums1,vector<int>&nums2){intm=nums1.size();intn=nums2.size();inttemp[(m+n)/2+1];//......
  • 使用Nginx反向代理解决http和https跨域问题
    使用Nginx作为反向代理来解决HTTP和HTTPS跨域问题,主要涉及到配置Nginx以添加CORS(跨源资源共享)相关的响应头。以下是具体的配置步骤和解释:通过上述配置,Nginx可以作为反向代理服务器,解决HTTP和HTTPS的跨域问题,同时确保通信的安全性和效率。配置CORS响应头:在Nginx的配置文件......
  • C语言第九周课——经典算法
    目录一、冒泡法排序1.1原理1.2代码实现(以升序排序为例) 1.3逻辑 1.4分析二、二分法查找2.1原理2.2代码实现 2.3逻辑2.4算法效率分析三、素数判断3.1原理3.2代码实现3.3逻辑3.4分析一、冒泡法排序1.1原理冒泡排序(BubbleSort)是一种简单的排序算法。它重......
  • 初识C语言2
    选择语句如果你好好学习,校招时拿到一个好offer,走上人生巅峰。如果你不学习,毕业等于失业,回家卖红薯。这就是选择!循环语句有些事必须一直做,比如写csdn,比如大家每天都要吃饭、喝水三种循环语句:while语句,for语句,do-while语句(我后面写csdn会详细讲)函数函数的特点就是简......
  • PTA-C语言-数组-字符串转换成十进制整数
    题目:输入一个以#结束的字符串,本题要求滤去所有的非十六进制字符(不分大小写),组成一个新的表示十六进制数字的字符串,然后将其转换为十进制数后输出。如果在第一个十六进制字符之前存在字符“-”,则代表该数是负数。输入格式:输入在一行中给出一个以#结束的非空字符串。输出格式:......
  • C语言入门到精通(第六版)——第十四章
    14、文件    文件是一组相关数据的有序集合,是程序设计中的一个重要概念。通常情况下,使用计算机主要是在使用文件。要进行数据处理,往往也需要通过文件来完成。14.1、文件概述    文件是一组相关数据的有序集合,这个数据集有一个名称,叫做文件名。    ......