1. 程式人生 > >第七屆藍橋杯JAVA B組省賽-四平方和試題

第七屆藍橋杯JAVA B組省賽-四平方和試題

四平方和

四平方和定理,又稱為拉格朗日定理:
每個正整數都可以表示為至多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); } } } }