OD统一考试
题解: Java / Python / C++
题目描述
如果三个正整数A
、B
、C
,A² + B² = C²
则为勾股数,
如果ABC
之间两两互质,即A
与B
,A
与C
,B
与C
均互质没有公约数,则称其为勾股数元组。
请求出给定 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加群”
🙏整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏