第七屆藍橋杯JAVA B組省賽-四平方和試題
阿新 • • 發佈:2019-01-01
四平方和
四平方和定理,又稱為拉格朗日定理:
每個正整數都可以表示為至多4個正整數的平方和。
如果把0包括進去,就正好可以表示為4個數的平方和。
比如:
5 = 0^2 + 0^2 + 1^2 + 2^2
7 = 1^2 + 1^2 + 1^2 + 2^2
(^符號表示乘方的意思)
對於一個給定的正整數,可能存在多種平方和的表示法。
要求你對4個數排序:
0 <= a <= b <= c <= d
並對所有的可能表示法按 a,b,c,d 為聯合主鍵升序排列,最後輸出第一個表示法
程式輸入為一個正整數N (N<5000000)
要求輸出4個非負整數,按從小到大排序,中間用空格分開
例如,輸入:
5
則程式應該輸出:
0 0 1 2
再例如,輸入:
12
則程式應該輸出:
0 2 2 2
再例如,輸入:
773535
則程式應該輸出:
1 1 267 838
資源約定:
峰值記憶體消耗(含虛擬機器) < 256M
CPU消耗 < 3000ms
請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入…” 的多餘內容。
所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。
注意:不要使用package語句。不要使用jdk1.7及以上版本的特性。
注意:主類的名字必須是:Main,否則按無效程式碼處理。
根據這道題可知,我們需要使用一個方法,就是回溯法,意思就是將所有可能情況遍歷一遍,同時需要控制每一次試數之後保證能夠回退到原來的數不變,因為此題只要輸出第一個可能的結果,所以需要保證找出第一個可能性就需要中斷試數,直接停止程式即可,相應的程式碼如下所示:
package com.lanqiao.seven.Test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
public class Demo08 {
public static ArrayList<Integer> list=new ArrayList<Integer>();//收集第一個可能結果
public static boolean flag=false;//只要找到第一個可能結果就為true,否則返回false
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int num=scan.nextInt();//接收控制檯輸入的數
digui(num);//進行遞迴操作
scan.close();
}
public static void digui(int num) {
// TODO Auto-generated method stub
//如果集合所容納得數超過4個,再試數也沒有意義,所以就需要返回上一層方法繼續試數
if(list.size()>4)
{
return;
}
//如果num==0,就證明找到了,如果此時list小於四個,就補零,否則直接輸出,並且flag為true終止遍歷
if(num==0)
{
if(list.size()==4)
{
flag=true;
print();
return;
}else {
while(list.size()<4)
{
list.add(0);
}
flag=true;
print();
return;
}
}else if(num<0)
{
return;
}else {
for(int i=0;i<Math.sqrt(num)+1;i++)
{
//這是回溯方法精髓,首先需要變換數,在進行遞迴,遞迴結束之後將數進行復原。
int temp=i*i;
list.add(i);
num-=temp;
if(!flag)
{
digui(num);
}
list.remove(list.size()-1);
num+=temp;
}
}
}
//輸出第一次成功之後的結果
public static void print() {
// TODO Auto-generated method stub
Iterator<Integer> its=list.iterator();
while(its.hasNext())
{
int c=its.next();
if(c!=list.get(list.size()-1))
{
System.out.print(c+" ");
}
else
{
System.out.print(c);
}
}
}
}