演算法 將正整數表示為平方數之和

2021-06-18 22:04:38 字數 1932 閱讀 6884

timus online judge

**上有這麼一道題目:

1073. square country

。這道題目的輸入是乙個不大於 60,000 的正整數,要求計算出該正整數最少能夠使用多少個正整數的平方和來表示。這道題目的時間限制是 1 秒

定理 369(lagrange 定理): 每個正整數都是四個平方數之和

在這個定理中,平方數是指整數(包括零)的平方。所以,我們有以下 c 語言程式(1073.c):

// 

#include #include int compute(int n)

int main(void)

上述程式中:

上述程式在 timus online judge **的執行時間是 0.015 秒。

上述題目有乙個進一步的版本:1593. square country. version 2,輸入改為不大於 1015 的正整數,時間限制還是 1 秒。上一節的程式做以下改動:

就可以適用於這道題目,但是執行結果是「time limit exceeded」。此時,需要更好的演算法。我們有以下 c 語言程式(1593.c):

// 

#include #include int compute(long long n)

int main(void)

在上述程式中:

這個程式在 timus online judge **的執行時間是 0.828 秒。這道題目的最佳執行時間是 0.031 秒,不知道使用什麼演算法可以這麼快。

《數論導引(第5版)》第 329 頁說:

n ≠ 4

a(8m + 7) 是 n 可以用三個平方數表示的乙個充分必要條件

第 318 頁有以下定理:

定理 366: 乙個數 n 是兩個平方之和,當且僅當在 n 的標準分解式中,它的所有形如 4m + 3 的素因子都有偶次冪
我們還有以下定理:

形如 4m + 3 的整數有形如 4m + 3 的素因子

前面的 1593.c 程式只能給出答案是幾個平方數之和,而對這些平方數是什麼一無所知。而 1073.c 程式倒是中規中矩地想要求解這些平方數是什麼,但是從 lagrange 定理得知最多只要四個平方數就夠了,所以該程式只求解到三個平方數的情況,其餘情況下答案肯定是 4 了。因此,我們將 1073.c 稍做修改,得到 1073b.c 用於列出這些平方數,如下所示:

#include #include #include static int a[5];

int compute(int n)

int main(int args, char* argv)

return 0;

}

上述程式中:

// 

#include typedef int bool;

const bool true = 1;

const bool false = 0;

bool issquare(int n, int v, int k)

bool issquaresum(int n, int m, int v, int k)

int compute(int n, int m)

int main(void)

這個程式本質上和鍵盤農夫園友的程式是沒有區別的。分析如下:

上述程式在 timus online judge **的執行時間是 0.031 秒,而第一小節中的 1073.c 的執行時間是 0.015 秒。

如果將上述程式作如下改動:

就可以適用於「1593. square country. version 2」,但是執行結果是「crash (stack overflow)」。

乙個正整數表示為n個連續正整數之和(第1屆第2題)

問題描述 乙個正整數有可能可以被表示為 n n 2 個連續正整數之和,如 15 1 2 3 4 5 15 4 5 6 15 7 8 編寫程式,根據輸入的任何乙個正整數,找出符合這種要求的所有連續正整數序列。樣例輸入 15樣例輸出 1 2 3 4 5 4 5 6 7 8 題意很好懂,這個題第一直覺想到...

將整數分解為連續正整數之和

將乙個整數 n 分解為連續正整數之和,如 15 可以分解為 15 1 2 3 4 5 15 4 5 6 15 7 8 計算從 i 開始連續 k 個數之和 sum k 2 i k 1 2 當 sum n 時,有 k k 2 i 1 k 2 n 0 變形為 i 2 n k k 1 2。在 2,2 n k...

判斷某整數是否為兩數平方之和

題 給定乙個整數 n,寫乙個程式判斷是否存在 2 個整數 a b a b 使得 a 2 b 2 n 如 輸入 n 5,輸出 true 輸入 n 7,輸出 false 思路 我們可以把整數n當成是乙個圓心在原點的園的半徑的平方。即圓的方程為 a 2 b 2 n。這樣,我們就可以使得a從1開始到根號n,...