【华为OD机试真题 C语言】19、勾股数元组 | 机试真题+思路参考+代码解析

该博客详细介绍了华为在线开发者(OD)机试中的一道C语言题目,涉及如何寻找指定范围内满足勾股数且两两互质的数元组。博主提供了思路分析和代码参考,包括如何判断两数互质,以及遍历并检查所有可能的勾股数元组,最后按要求排序输出结果。
摘要由CSDN通过智能技术生成


🍂个人博客首页: KJ.JK
 
🍂专栏介绍: 华为OD机试真题汇总,定期更新华为OD各个时间阶段的机试真题,每日定时更新,本专栏将使用C语言进行更新解答,包含真题,思路分析,代码参考,欢迎大家订阅学习


一、题目


🎃题目描述

如果3个正整数(a,b,c)满足a2 + b2 = c2的关系,则称(a,b,c)为勾股数(著名的勾三股四弦五),
 
为了探索勾股数的规律,我们定义如果勾股数(a,b,c)之间两两互质(即a与b,a与c,b与c之间均互质,没有公约数),则其为勾股数元组(例如(3,4,5)是勾股数元组,(6,8,10)则不是勾股数元组)。
 
请求出给定范围[N,M]内,所有的勾股数元组。


🎃输入输出

输入
起始范围N,1 <= N <= 10000
结束范围M,N < M <= 10000
 
输出
1、a,b,c请保证a < b < c,输出格式:a b c;
2、多组勾股数元组请按照a升序,b升序,最后c升序的方式排序输出;
3、给定范围中如果找不到勾股数元组时,输出”NA“。


🎃样例1

输入
1

20


输出
3 4 5

5 12 13

8 15 17


说明:

[1, 20]范围内勾股数有:(3 4 5)(5 12 13)(6 8 10)(8 15 17)(9 12 15)(12 16 20);

其中,满足(a,b,c)之间两两互质的勾股数元组有:(3 4 5)(5 12 13)(8 15 17);

按输出描述中顺序要求输出结果。


🎃样例2

输入
5
10

输出
NA

说明:
[5, 10]范围内勾股数有:(6 8 10);

其中,没有满足(a,b,c)之间两两互质的勾股数元组;

给定范围中找不到勾股数元祖,输出”NA

二、思路参考


1、首先,我们需要编写一个函数来判断两个数是否互质。互质的条件是它们的最大公约数为 1。我们可以使用辗转相除法来求两个数的最大公约数。如果最大公约数为 1,则两个数互质。

2、接下来,我们可以使用两重循环遍历范围 [N, M] 内的所有数对 (a, b),其中 N <= a < b <= M。对于每个数对,我们计算 c 的值,并判断是否满足勾股数条件和两两互质条件。

3、勾股数条件是 a^2 + b^2 = c^2。我们计算 c 的平方,然后取其平方根,将结果转换为整数。如果平方根的整数部分的平方等于 c 的平方,则满足勾股数条件。

4、在判断勾股数条件的基础上,我们还需要判断 (a, b, c) 是否两两互质。即判断 a 和 b、a 和 c、b 和 c 是否互质。我们可以调用之前编写的判断互质的函数进行判断。

5、如果满足勾股数条件和两两互质条件,将勾股数元组 (a, b, c) 添加到结果集合中。

6、最后,我们对结果集合进行排序,按照 a 升序、b 升序、最后 c 升序的方式排序。

根据题目要求的输出格式,按照每个勾股数元组一行的形式输出结果。

如果在给定范围内找不到勾股数元组,则输出 “NA”。


三、代码参考

#include <stdio.h>
#include <stdbool.h>
#include <math.h>

// 判断两个数是否互质
bool areCoprime(int a, int b) {
    int temp;
    while (b != 0) {
        temp = b;
        b = a % b;
        a = temp;
    }
    return a == 1;
}

int main() {
    int N, M;
    scanf("%d %d", &N, &M);

    bool found = false; // 标记是否找到勾股数元组
    for (int a = N; a < M; a++) {
        for (int b = a + 1; b < M; b++) {
            int c_square = a * a + b * b;
            int c = (int)sqrt(c_square);
            if (c * c == c_square && areCoprime(a, b) && areCoprime(a, c) && areCoprime(b, c)) {
                printf("%d %d %d\n", a, b, c);
                found = true;
            }
        }
    }

    if (!found) {
        printf("NA\n");
    }

    return 0;
}


代码2(考虑c小于m)

#include <stdio.h>
#include <stdbool.h>
#include <math.h>

// 判断两个数是否互质的函数
bool areCoprime(int a, int b) {
    int temp;
    while (b != 0) {
        temp = b;  // 将b的值暂存起来
        b = a % b; // 计算a除以b的余数,赋值给b
        a = temp;  // 将暂存的b值赋给a
    }
    return a == 1; // 如果最大公约数是1,返回true,表示互质
}

int main() {
    int N, M;
    scanf("%d %d", &N, &M); // 从标准输入读取N和M的值

    bool found = false; // 标记是否找到勾股数元组
    // 外层循环,遍历所有可能的a值
    for (int a = N; a <= M; a++) {
        // 内层循环,遍历所有可能的b值,b始终大于a
        for (int b = a + 1; b <= M; b++) {
            int c_square = a * a + b * b; // 计算c的平方
            int c = (int)sqrt(c_square); // 计算c的值
            // 检查c是否为整数,并确保c不大于M
            // 同时检查a, b, c是否两两互质
            if (c * c == c_square && c <= M && areCoprime(a, b) && areCoprime(a, c) && areCoprime(b, c)) {
                printf("%d %d %d\n", a, b, c); // 输出勾股数元组
                found = true; // 设置找到勾股数元组的标志
            }
        }
    }

    if (!found) {
        printf("NA\n"); // 如果没有找到,输出NA
    }

    return 0;
}



作者:KJ.JK

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KJ.JK

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值