华为OD机试 - 勾股数元组(Python/JS/C/C++ 2024 E卷 100分)

在这里插入图片描述

2025华为OD机试题库(按算法分类):2025华为OD统一考试题库清单(持续收录中)以及考点说明(Python/JS/C/C++)。

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

一、题目描述

如果三个正整数A、B、C ,A²+B²=C²则为勾股数 如果ABC之间两两互质,即A与B,A与C,B与C均互质没有公约数, 则称
其为勾股数元组。 请求出给定n~m范围内所有的勾股数元组。

二、输入描述

起始范围 1 < n < 10000 n < m < 10000

1
20

三、输出描述

ABC保证A

3 4 5
5 12 13
8 15 17

四、测试用例

测试用例1

1、输入

1 10

2、输出

3 4 5

3、说明

区间 [1,10] 内只有 3 4 5 满足条件。

测试用例2

1、输入

20
100

2、输出

20 21 29
28 45 53
33 56 65
36 77 85
39 80 89
48 55 73
65 72 97

3、说明

区间 [20,100] 内存在多个满足条件的元组,上述为常见的几组原始(原始且互质)勾股数。

五、解题思路

  1. 读取输入的起始范围,记为n和m;
  2. 创建一个列表lists,用于保存找到的勾股数元组;
  3. 遍历范围n到m之间的所有整数,记当前整数为i:
    • 在范围[i+1, m]内遍历所有整数,记当前整数为j:
    • 若满足check1(i, j, m),即i、j、(i²+j²)的平方根均为整数且不超过m,满足勾股数的条件:
    • 创建一个列表list,将i、j和(i²+j²)的平方根按升序添加到list中;
    • 将list添加到lists中;
  4. 遍历lists,记当前元组索引为idx:
    • 若满足check2(list.get(0), list.get(1), list.get(2)),即元组中的三个数存在公约数:
    • 从lists中移除当前元组;
    • 将idx重置为0;
    • 否则,递增idx;
  5. 遍历结束后,输出剩余的lists中的元组;

六、Python算法源码

import math

# 读取输入的起始范围 n 和结束范围 m
n = int(input().strip())
m = int(input().strip())
found = False  # 标记是否找到符合条件的元组

# 枚举 A 从 n 到 m
for a in range(n, m + 1):
    # 枚举 B 从 a+1 到 m
    for b in range(a + 1, m + 1):
        c_square = a * a + b * b  # 计算 A^2 + B^2
        c = int(math.sqrt(c_square))  # 计算 c = √(A^2+B^2)
        # 判断 c 是否为整数,并且 c 在范围内且大于 B
        if c * c == c_square and c <= m and c > b:
            # 判断三个数是否两两互质,使用 math.gcd 函数
            if math.gcd(a, b) == 1 and math.gcd(a, c) == 1 and math.gcd(b, c) == 1:
                print(a, b, c)  # 输出符合条件的元组
                found = True

# 如果没有找到任何符合条件的元组,则输出 "Na"
if not found:
    print("Na")

七、JavaScript算法源码

// 定义计算两个数最大公约数的函数(欧几里得算法)
function gcd(a, b) {
    return b === 0 ? a : gcd(b, a % b);
}

// 使用 Node.js 读取标准输入
const readline = require('readline');

// 创建 readline 接口
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

let lines = []; // 存储输入行
rl.on('line', (line) => {
    lines.push(line.trim());
}).on('close', () => {
    // 读取起始范围 n 和结束范围 m
    let n = parseInt(lines[0]);
    let m = parseInt(lines[1]);
    let found = false; // 标记是否找到符合条件的元组

    // 枚举 A 从 n 到 m
    for (let a = n; a <= m; a++) {
        // 枚举 B 从 a+1 到 m
        for (let b = a + 1; b <= m; b++) {
            let cSquare = a * a + b * b; // 计算 A^2 + B^2
            let c = Math.floor(Math.sqrt(cSquare)); // 计算 c = √(A^2+B^2)
            // 判断 c 是否为整数,且 c 在范围内且大于 B
            if (c * c === cSquare && c <= m && c > b) {
                // 判断三个数是否两两互质
                if (gcd(a, b) === 1 && gcd(a, c) === 1 && gcd(b, c) === 1) {
                    console.log(a + " " + b + " " + c); // 输出符合条件的元组
                    found = true;
                }
            }
        }
    }
    // 若没有找到符合条件的元组,则输出 "Na"
    if (!found) {
        console.log("Na");
    }
});

八、C算法源码

#include 
#include 

// 定义函数计算两个数的最大公约数(递归实现欧几里得算法)
int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
}

int main(){
    int n, m;
    // 读取输入的起始范围 n 和结束范围 m
    scanf("%d%d", &n, &m);
    int found = 0; // 标记是否找到符合条件的元组

    // 枚举 A 从 n 到 m
    for (int a = n; a <= m; a++){
        // 枚举 B 从 a+1 到 m
        for (int b = a + 1; b <= m; b++){
            int cSquare = a * a + b * b; // 计算 A^2 + B^2
            int c = (int)sqrt(cSquare);  // 计算 c = √(A^2+B^2)
            // 判断 c 是否为整数且满足 c 在 [b+1, m] 范围内
            if (c * c == cSquare && c <= m && c > b){
                // 判断 a, b, c 是否两两互质
                if (gcd(a, b) == 1 && gcd(a, c) == 1 && gcd(b, c) == 1){
                    printf("%d %d %d\n", a, b, c); // 输出符合条件的元组
                    found = 1;
                }
            }
        }
    }
    // 若未找到任何符合条件的元组,则输出 "Na"
    if (!found){
        printf("Na\n");
    }
    return 0;
}

九、C++算法源码

#include 
#include 
using namespace std;

// 定义函数计算两个数的最大公约数(递归实现欧几里得算法)
int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
}

int main(){
    int n, m;
    // 读取输入的起始范围 n 和结束范围 m
    cin >> n >> m;
    bool found = false; // 标记是否找到符合条件的元组

    // 枚举 A 从 n 到 m
    for (int a = n; a <= m; a++){
        // 枚举 B 从 a+1 到 m
        for (int b = a + 1; b <= m; b++){
            int cSquare = a * a + b * b; // 计算 A^2 + B^2
            int c = (int) sqrt(cSquare); // 计算 c = √(A^2+B^2)
            // 判断 c 是否为整数,且满足 c 在范围内且大于 B
            if (c * c == cSquare && c <= m && c > b){
                // 判断 a, b, c 是否两两互质
                if (gcd(a, b) == 1 && gcd(a, c) == 1 && gcd(b, c) == 1){
                    cout << a << " " << b << " " << c << endl; // 输出符合条件的元组
                    found = true;
                }
            }
        }
    }
    // 若未找到任何符合条件的元组,则输出 "Na"
    if (!found)
        cout << "Na" << endl;
    return 0;
}


下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)

本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

在这里插入图片描述

你可能感兴趣的:(搬砖工逆袭Java架构师,华为od,python,javascript)