gcd(a,b)=gcd(b,a%b)

本文详细证明了当a和b互质时,gcd(a,b)等于gcd(a-b,b)和gcd(a-2b,b)等的性质,通过gcd(A-B,B)的特殊情况k=1来推导。关键步骤展示了如何利用基本的数论原理和互质条件简化计算。

设gcd(a,b)=m;
a=Am,b=Bm,其中A,B互质;
a-b=m(A-B),于是gcd(a-b,b)=m;
简单证明:
设gcd(A-B,B)=k;
k|A-B,k|B;
==>K|A,k|B,又因为gcd(A,B)=1;
所以k=1;
gcd(a,b)=gcd(a-b,b);

//
gcd(a,b)=gcd(b,a%b)
证明gcd(a,b)=gcd(a-b,b)=gcd(a-2b,b)=gcd(a-nb,b);
又a-nb=r;
所以gcd(a,b)=gcd(a-b,b)=gcd(b,a%b);

你提供的 C 代码是用于计算两个整数的**最大公约数(GCD, Greatest Common Divisor)**,使用的是 **欧几里得算法(辗转相除法)**。但代码中存在一个逻辑问题:**在输入后又重新赋值了 `a=12; b=18;`**,导致用户输入被覆盖。 下面我们先分析代码运行结果,再给出修正版本和详细解释。 --- ### ❌ 原始代码的问题 ```c scanf("%d %d", &a, &b); a = 12; b = 18; // ← 这行覆盖了用户的输入! ``` > 用户输入的数据没有实际作用,程序始终计算 `gcd(12, 18)`。 --- ### ✅ 修正后的完整代码(保留输入或固定值) #### 方案一:让用户输入 a 和 b ```c #include <stdio.h> int main() { int a, b, t; printf("请输入两个整数: "); scanf("%d %d", &a, &b); // 保存原始值以便输出 int original_a = a, original_b = b; while (b != 0) { t = a % b; a = b; b = t; printf("a=%d, b=%d, t=%d\n", a, b, t); } printf("gcd(%d, %d) = %d\n", original_a, original_b, a); return 0; } ``` #### 方案二:固定测试值(调试用) ```c #include <stdio.h> int main() { int a = 12, b = 18, t; printf("计算 gcd(12, 18)\n"); while (b != 0) { t = a % b; a = b; b = t; printf("a=%d, b=%d, t=%d\n", a, b, t); } printf("gcd = %d\n", a); return 0; } ``` --- ### 🔍 算法原理:欧几里得算法(辗转相除法) > 核心公式: > $$ \gcd(a, b) = \gcd(b, a \mod b) $$ 不断将大数替换为小数,小数替换为余数,直到余数为 0,此时的 `a` 就是最大公约数。 --- ### 🧮 执行过程(以 `a=12, b=18` 为例) | 步骤 | a | b | t = a % b | 新 a | 新 b | |------|----|----|-----------|------|------| | 初始 | 12 | 18 | — | — | — | | 1 | 12 | 18 | 12 % 18 = 12 | 18 | 12 | | 2 | 18 | 12 | 18 % 12 = 6 | 12 | 6 | | 3 | 12 | 6 | 12 % 6 = 0 | 6 | 0 | | 结束 | → gcd = 6 | #### 输出: ``` a=18, b=12, t=12 a=12, b=6, t=6 a=6, b=0, t=0 gcd = 6 ``` > ✅ 正确结果:`gcd(12, 18) = 6` --- ### 💡 补充说明 - `while (b != 0)` 是循环终止条件:当 `b == 0` 时,`a` 就是 GCD。 - 不需要处理负数?可以加绝对值处理(可选): ```c a = abs(a); b = abs(b); ``` --- ### ✅ 完整健壮版本(支持负数、零判断) ```c #include <stdio.h> #include <stdlib.h> // for abs() int gcd(int a, int b) { a = abs(a); b = abs(b); // 转为正数 while (b != 0) { int t = a % b; a = b; b = t; } return a; } int main() { int a, b; printf("请输入两个整数: "); scanf("%d %d", &a, &b); printf("gcd(%d, %d) = %d\n", a, b, gcd(a, b)); return 0; } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值