勾股数元组

如果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 输出描述:

a,b,c请保证a < b < c,输出格式:a b c; 多组勾股数元祖请按照a升序,b升序,最后c升序的方式排序输出; 给定范围中如果找不到勾股数元祖时,输出”NA”。

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class Pythagoras {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Pythagoras test = new Pythagoras();
		int m = 1;
		int n = 10000;
		long start = System.currentTimeMillis();
		List<TreeSet<Integer>> res = test.triplePythagoras(m, n);
		System.out.println(res.size());
		if (res.isEmpty()) {
			System.out.println("NA");
		}else {
			for (Set<Integer> s : res) {
				System.out.println(s);
			}
		}
		long time = System.currentTimeMillis() - start;
		System.out.println("Time use(ms):" + time);
	}

	//按照a,b,c的顺序输出
	public List<TreeSet<Integer>> triplePythagoras(int m, int n) {
		List<TreeSet<Integer>> list = new ArrayList<>();
		//确保n>m
		if (m > n) {
			int t = m;
			m = n;
			n = t;
		}
		int k = (int) (Math.ceil(Math.sqrt(n >> 1)));
		int a, b, c;
		for (int i = m; i < k; i++) {
			for (int j = i + 1; j < k; j++) {
				if (isOdd(i + j) && gcd(i, j) == 1) {
					a = j * j - i * i;
					b = 2 * i * j;
					c = j * j + i * i;
					TreeSet<Integer> set = new TreeSet<>();
					set.add(a);
					set.add(b);
					set.add(c);
					list.add(set);
				}
			}
		}
		Collections.sort(list, new Comparator<TreeSet<Integer>>() {
			@Override
			public int compare(TreeSet<Integer> o1, TreeSet<Integer> o2) {
				//return o1.toString().compareTo(o2.toString());
				int t=o1.first()-o2.first();
				if (t==0) {
					return o1.last()-o2.last();
				}
				return t;
			}
		});
		return list;
	}

	//判断是否为奇数
	private boolean isOdd(int a) {
		if ((a & 1) == 1) { //是奇数
			return true;
		}
		return false;
	}

	//找最大公约数
	private int gcd(int a, int b) {
		int r = 0;
		while (b != 0) {
			r = a % b;
			a = b;
			b = r;
		}
		return a;
	}
}

名称 缩写
1 [3, 4, 5]
2 [5, 12, 13]
3 [7, 24, 25]
4 [8, 15, 17]
5 [9, 40, 41]
6 [11, 60, 61]
7 [12, 35, 37]
8 [13, 84, 85]
9 [15, 112, 113]
10 [16, 63, 65]
11 [17, 144, 145]
12 [19, 180, 181]
13 [20, 21, 29]
14 [20, 99, 101]
15 [21, 220, 221]
16 [23, 264, 265]
17 [24, 143, 145]
18 [25, 312, 313]
19 [27, 364, 365]
20 [28, 45, 53]
21 [28, 195, 197]
22 [29, 420, 421]
23 [31, 480, 481]
24 [32, 255, 257]
25 [33, 56, 65]
26 [33, 544, 545]
27 [35, 612, 613]
28 [36, 77, 85]
29 [36, 323, 325]
30 [37, 684, 685]
31 [39, 80, 89]
32 [39, 760, 761]
33 [40, 399, 401]
34 [41, 840, 841]
35 [43, 924, 925]
36 [44, 117, 125]
37 [44, 483, 485]
38 [48, 55, 73]
39 [51, 140, 149]
40 [52, 165, 173]
41 [57, 176, 185]
42 [60, 91, 109]
43 [60, 221, 229]
44 [65, 72, 97]
45 [68, 285, 293]
46 [69, 260, 269]
47 [75, 308, 317]
48 [76, 357, 365]
49 [84, 187, 205]
50 [84, 437, 445]
51 [85, 132, 157]
52 [87, 416, 425]
53 [88, 105, 137]
54 [93, 476, 485]
55 [95, 168, 193]
56 [96, 247, 265]
57 [104, 153, 185]
58 [105, 208, 233]
59 [105, 608, 617]
60 [111, 680, 689]
61 [115, 252, 277]
62 [119, 120, 169]
63 [120, 209, 241]
64 [120, 391, 409]
65 [123, 836, 845]
66 [132, 475, 493]
67 [133, 156, 205]
68 [135, 352, 377]
69 [136, 273, 305]
70 [140, 171, 221]
71 [145, 408, 433]
72 [152, 345, 377]
73 [155, 468, 493]
74 [160, 231, 281]
75 [161, 240, 289]
76 [165, 532, 557]
77 [168, 425, 457]
78 [175, 288, 337]
79 [180, 299, 349]
80 [185, 672, 697]
81 [189, 340, 389]
82 [195, 748, 773]
83 [203, 396, 445]
84 [204, 253, 325]
85 [207, 224, 305]
86 [217, 456, 505]
87 [220, 459, 509]
88 [225, 272, 353]
89 [228, 325, 397]
90 [231, 520, 569]
91 [252, 275, 373]
92 [259, 660, 709]
93 [261, 380, 461]
94 [279, 440, 521]
95 [280, 351, 449]
96 [297, 304, 425]
97 [308, 435, 533]
98 [315, 572, 653]
99 [319, 360, 481]
100 [336, 377, 505]
101 [341, 420, 541]
102 [396, 403, 565]