第七屆藍橋杯第8題:四平方和
阿新 • • 發佈:2018-12-30
四平方和
四平方和定理,又稱為拉格朗日定理:
每個正整數都可以表示為至多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
請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入...” 的多餘內容。
所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。
注意: main函式需要返回0
注意: 只使用ANSI C/ANSI C++ 標準,不要呼叫依賴於編譯環境或作業系統的特殊函式。
注意: 所有依賴的函式必須明確地在原始檔中 #include <xxx>, 不能通過工程設定而省略常用標頭檔案。
四平方和定理,又稱為拉格朗日定理:
每個正整數都可以表示為至多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
請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入...” 的多餘內容。
所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。
注意: main函式需要返回0
注意: 只使用ANSI C/ANSI C++ 標準,不要呼叫依賴於編譯環境或作業系統的特殊函式。
注意: 所有依賴的函式必須明確地在原始檔中 #include <xxx>, 不能通過工程設定而省略常用標頭檔案。
提交時,注意選擇所期望的編譯器型別。
分析:直接窮舉:
#include <stdio.h> #include <math.h> int main() { int a, b, c, n, flag = 0; double maxN, d; scanf("%d", &n); maxN = sqrt(n); for(a = 0; a <= maxN; a ++){ for(b = a; b <= maxN; b ++){ for(c = b; c <= maxN; c ++){ d = sqrt(n - a*a - b*b - c*c); if(d == (int)d){ printf("%d %d %d %d\n", a, b, c, (int)d); flag = 1; break; } } if(flag) break; } if(flag) break; } return 0; }
大神程式碼:
#include <stdio.h> #include <math.h> int mpt[5000010] ={0}; //mpt[i] = 1表示i 能夠用兩個完全平方數相加而得。 int n; void init() { for(int i = 0 ; i*i <= n ; i ++) for(int j = 0 ; j*j <=n ; j ++) if(i*i+j*j <= n) mpt[i*i+j*j] = 1; } int main() { int flag = false; scanf("%d",&n); init(); for(int i = 0 ; i * i <= n ; i ++) { for(int j = 0 ; j * j <= n ; j ++){ if(mpt[n - i*i - j*j] == 0) continue; //如果剩下的差用兩個完全平方數不能組合出來就不繼續 for(int k = 0 ; k * k <= n ; k ++) { int temp = n - i*i - j*j - k*k; double l = sqrt((double) temp); if(l == (int)l ) { printf("%d %d %d %d\n",i,j,k,(int)l); flag = true; break; } } if(flag)break; } if(flag)break; } return 0; }