勾股数 - 华为OD统一考试

发布时间:2024年01月15日

OD统一考试

题解: Java / Python / C++

alt

题目描述

如果三个正整数ABCA2 + B2 = C2 则为勾股数,

如果ABC之间两两互质,即ABACBC均互质没有公约数,则称其为勾股数元组。

请求出给定 n ~ m 范围内所有的勾股数元组。

输入描述

起始范围

1 < n < 10000
n < m < 10000

输出描述

ABC保证A < B < C

输出格式A B C

多组勾股数元组,按照A B C升序的排序方式输出。

若给定范围内,找不到勾股数元组时,输出Na

示例1

输入:
1
20

输出:
3 4 5
5 12 13
8 15 17

示例2

输入:
5
10

输出:
Na

题解

勾股数是指满足勾股定理的三个正整数,即满足条件 A 2 + B 2 = C 2 A^2+B^2=C^2 A2+B2=C2。题目要求在给定的范围 [n, m] 内找到所有的勾股数元组,其中 A<B<C,且 A 与 B, A 与 C, B 与 C 均互质,即没有公约数。

解题思路:遍历范围内的所有可能的 A 和 B,然后通过勾股定理计算得到 C,判断是否满足互质条件。如果满足条件,则输出这个勾股数元组。最后,如果没有找到任何符合条件的勾股数元组,则输出 “Na”。

在代码中,使用两层循环遍历范围内的 A 和 B,通过 Math.sqrt 计算 C。通过辗转相除法计算两个数的最大公约数(gcd 函数)。如果满足条件,则输出结果。

代码中的 found 变量用于标记是否找到了符合条件的勾股数元组。如果最终 found 仍然为 false,说明没有找到符合条件的勾股数元组,输出 “Na”。

时间复杂度分析:两层循环嵌套,每次循环中包含常数时间的计算,因此时间复杂度为 O((m?n)^2))。

空间复杂度分析:仅使用了常数个变量,空间复杂度为 O(1)。

Java

import java.util.Scanner;
/**
 * @author code5bug
 */
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {
            int n = in.nextInt();
            int m = in.nextInt();
            boolean found = false;
            for (int a = n; a <= m; a++) {
                for (int b = a + 1; b <= m; b++) {
                    int c = (int) Math.sqrt(a * a + b * b);
                    if (c > m) break;
                    if (c * c == a * a + b * b) {
                        if (gcd(a, b) == 1 && gcd(b, c) == 1) {
                            System.out.println(String.format("%d %d %d", a, b, c));
                            found = true;
                        }
                    }
                }
            }
            if (!found) {
                System.out.println("Na");
            }
        }
    }

    private static int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }
}

Python

import math

while True:
    try:
        n, m = int(input()), int(input())
        found = False
        for a in range(n, m):
            for b in range(a + 1, m):
                cc = a * a + b * b
                if cc > m * m or math.gcd(a, b) != 1:
                    continue

                c = int(math.sqrt(cc))
                if c * c == cc and math.gcd(a, c) == 1:
                    print(a, b, c)
                    found = True

        if not found:
            print("Na")
    except EOFError:
        break

C++

#include <iostream>
#include <cmath>
using namespace std;

int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
}

int main() {
    int n, m;
    while (cin >> n >> m) {
        bool found = false;
        for (int a = n; a <= m; a++) {
            for (int b = a + 1; b <= m; b++) {
                int c = (int) sqrt(a * a + b * b);
                if (c > m) break;
                
                if (c * c == a * a + b * b) {
                    if (gcd(a, b) == 1 && gcd(a, c) == 1) {
                        cout << a << " " << b << " " << c << endl;
                        found = true;
                    }
                }
            }
        }
        if (!found) {
            cout << "Na" << endl;
        }
    }
    return 0;
}

????华为OD机试面试交流群每日真题分享): 加V时备注“华为od加群”

🙏整理题解不易, 如果有帮助到您,请给点个赞 ???? 和收藏 ?,让更多的人看到。🙏🙏🙏

文章来源:https://blog.csdn.net/user_longling/article/details/135601019
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。