12 cm: (3,4,5)
24 cm: (6,8,10)
30 cm: (5,12,13)
36 cm: (9,12,15)
40 cm: (8,15,17)
48 cm: (12,16,20)
In contrast, some lengths of wire, like 20 cm, cannot be bent to form an integer sided right angle triangle, and other lengths allow more than one solution to be found; for example, using 120 cm it is possible to form exactly three different integer sided right angle triangles.
120 cm: (30,40,50), (20,48,52), (24,45,51)
Given that L is the length of the wire, for how many values of L 1,500,000 can exactly one integer sided right angle triangle be formed?
Note: This problem has been changed recently, please check that you are using the right parameters.
下面是java解题方法:
public static void main(String[] args) { Map<Integer, ABC> dict = new HashMap<Integer, ABC>(); int L = 1500000; int M = (int)Math.sqrt(L / 2); for (int m = 1; m <= M; m++) { for (int n = 1; n < m; n++) { int a = m * m - n * n; int b = 2 * m * n; int c = m * m + n * n; int l = a + b + c; int k = L / l; for (int i = 1; i <= k; i++) { int[] abc = { i * a, i * b, i * c }; Arrays.sort(abc); check(i, l, abc, dict); } } } int count = 0; for (ABC abc : dict.values()) { count += abc.got; } System.out.println(count); } private static void check(int i, int l, int[] abc, Map<Integer, ABC> dict) { int ll = i * l; ABC tmp = dict.get(ll); if (tmp != null) { if (tmp.got == 1) { int[] tmp1 = tmp.abc; for (int x = 0; x < 3; x++) { if (tmp1[x] != abc[x]) { tmp.got = 0; break; } } } } else { dict.put(ll, new ABC(abc)); } } static class ABC { public ABC(int[] abc) { this.abc = abc; } int got = 1; int[] abc; }
这个解法的时间在秒级,解法利用了下面勾股数的性质:
1,通过a = m^2 − n^2, b = 2mn, c = m^2 + n^2 (1)可以生成所有的素勾股数和一部分派生勾股数(a,b,c),其在(m>n,m,n为正整数);
2,勾股数分为素勾股数和派生勾股数,而且所有派生勾股数都是由素勾股数派生而来的;
3,根据1,2,利用式(1),遍历m,n并加上派生规则可以生成所有勾股数。
注:正整数a,b,c满足a^2+b^2=c^2<=>(a,b,c)是勾股数,如果(a,b,c)=1(即a,b,c互素),则(a,b,c)称为素勾股数,对于整数k,(ka,kb,kc)是由(a,b,c)派生的勾股数。