Fermat-Lagrange 定理指出,任何一个自然数都可以表示为 4 个整数的平斱和,这种表示形式称
作费马-拉格朗日分解,比如:30等于1的平方加2的平方加3的平方加4的平方。
最直接版:直接枚举出所有可能,一一检查是否符合分解定理。
package com.company; public class Main { public static void main(String[] args) { // write your code here FermatLagrange(30); } public static void FermatLagrange(int n){ int k = (int)Math.sqrt(n); int[] a = new int[4]; for(a[0]=k; a[0]>=0; a[0]--){ for(a[1]=k; a[1]>=0; a[1]--){ for(a[2]=k; a[2]>=0; a[2]--){ for(a[3]=k; a[3]>=0; a[3]--){ if(sum(a) == n){ print(a); } } } } } } static int sum(int a[]){ int sum = 0; for (int i=0; i<4; i++) sum += (a[i]*a[i]); return sum; } static void print(int a[]){ for (int i=0; i<4; i++) { System.out.print(a[i] + " "); } System.out.println(); } }
回溯版:减少不必要的循环次数
package com.company; public class Main { public static void main(String[] args) { // write your code here FermatLagrange(30); } public static void FermatLagrange(int n){ int k = (int)Math.sqrt(n); int[] a = new int[4]; for(a[0]=k; a[0]>=0; a[0]--){ for(a[1]=k; a[1]>=0; a[1]--){ if(!check(a,n)) continue; //如果四个数的和大于n则进行下次循环 for(a[2]=k; a[2]>=0; a[2]--){ if(!check(a,n)) continue; for(a[3]=k; a[3]>=0; a[3]--){ if(!check(a,n)) continue; if(sum(a) == n){ print(a); } } } } } } static boolean check(int a[],int n){ if (sum(a) > n) return false; return true; } static int sum(int a[]){ int sum = 0; for (int i=0; i<4; i++) sum += (a[i]*a[i]); return sum; } static void print(int a[]){ for (int i=0; i<4; i++) { System.out.print(a[i] + " "); } System.out.println(); } }