四平方和解題報告---窮舉
阿新 • • 發佈:2019-01-24
四平方和
四平方和定理,又稱為拉格朗日定理:
每個正整數都可以表示為至多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
思路:提前窮舉出兩個數的平方和能組成的數,然後用三個for迴圈實現
時間複雜度:O(n^2)
可能經驗不足吧...竟然蠢到用了4個for迴圈(下次做題記得帶腦子...)
AC Code:
#include <cstdio> #include <cmath> #include<algorithm> #include<iostream> #include<cstring> using namespace std; int n; bool vv[5000005]; void init(){ memset(vv, false, sizeof(vv)); for(int i = 0; i * i <= n; i++){ for(int j = 0; j * j <= n; j++){ vv[i * i + j * j] = true; //兩個數的平方能夠組成的數 } } } int main(){ while(scanf("%d", &n) != EOF){ int len = sqrt(n); init(); bool flag = true; for(int i = 0; i <= len && flag; i++){ for(int j = i; j <= len && flag; j++){ if(!vv[n - i * i - j * j]) continue; for(int k = j; k <= len && flag; k++){ double t = sqrt(n - i * i - j * j - k * k); if(t == (int)t){ flag = false; printf("%d %d %d %d\n", i, j, k, (int)t); break; } } } } } return 0; }
這種方法也可以:O(n^3)
#include <cstdio> #include <cmath> #include<algorithm> #include<iostream> using namespace std; int n; int main(){ while(scanf("%d", &n) != EOF){ int len = sqrt(n); bool flag = true; for(int i = 0; i <= len && flag; i++){ for(int j = i; j <= len && flag; j++){ for(int k = j; k <= len && flag; k++){ double t = sqrt(n - i * i - j * j - k * k); if(t == (int)t){ flag = false; printf("%d %d %d %d\n", i, j, k, (int)t); break; } } } } } return 0; }