1. 程式人生 > >計蒜客:四平方和

計蒜客:四平方和

問題:

四平方和定理,又稱為拉格朗日定理:每個正整數都可以表示為至多四個正整數的平方和。
如果把 0 0 包括進去,就正好可以表示為四個數的平方和。
比如:
5 = 0

2 + 0 2 + 1 2
+ 2 2 \displaystyle 5 = 0^2 + 0^2 + 1^2 + 2^2
7
= 1 2 + 1 2 + 1 2 + 2 2 \displaystyle 7 = 1^2 + 1^2 + 1^2 + 2^2

則對於一個給定的正整數 n n ,可以表示為: n = a 2 + b 2 + c 2 + d 2 n = a^2 + b^2 + c^2 + d^2
你需要求出 字典序 最小的一組解 a , b , c , d a,b,c,d
字典序大小:從左到右依次比較,如果相同則比較下一項,直到有一項不同,較小的一方字典序更小,反之字典序更大,所有項均相同則二者字典序相同。

輸入格式:
程式輸入為一個正整數 N ( 1 N 5000000 ) N(1 \leq N \leq 5000000)

輸出格式:
輸出四個非負整數 a , b , c , d a,b,c,d ,中間用空格分開。

樣例輸入:

5

樣例輸出

0 0 1 2

樣例輸入:

12

樣例輸出:

0 2 2 2

題解:

解法一:

思路:用四層for迴圈,從0開始,當找到第一個就輸出(但測試超時)

#include<iostream>
#include<math.h>
using namespace std;
int main(void) 
{
	int n;
	cout << "請輸入一個數字(1-5000000):";
	cin >> n;
	for (int i = 0; i < sqrt(n); i++)
	{
		for (int j = 0; j < sqrt(n); j++)
		{
			for (int x = 0; x < sqrt(n); x++)
			{
				for (int y = 0; y < sqrt(n); y++)
					if ((i*i + j * j + x * x + y * y) == n)
					{
						cout << i << " " << j << " " << x << " " << y;
						system("pause");
						return 0;
					}

			}

		}
	}
	system("pause");
	return 0;
}

解法二:

思路:可以只遍歷三個數,最後一個數用 n 減去前三個數的平方和再開根號得到,判斷條件是,開出的根號正好是個整數

#include<iostream>
#include<math.h>
using namespace std;
int main(void) 
{
	int n;
	cout << "請輸入一個數字(1-5000000):";
	cin >> n;
	for (int i = 0; i < sqrt(n); i++)
	{
		for (int j = 0; j < sqrt(n); j++)
		{
			for (int k = 0; k < sqrt(n); k++)
			{
				if (sqrt(n - (i*i + j * j + k * k)) == int(sqrt(n - (i*i + j * j + k * k))))
				{
					cout << i << " " << j << " " << k << " " << int(sqrt(n - (i*i + j * j + k * k)));
					system("pause");
					return 0;
				}
			}
		}
	}
	system("pause");
	return 0;
}