4kyu Sums of Perfect Squares
题目背景:
The task is simply stated. Given an integer n (3 < n < 109), find the length of the smallest list of perfect squares which add up to n.
Examples:
sum_of_squares(17) = 2
17 = 16 + 1 (4 and 1 are perfect squares).
sum_of_squares(15) = 4
15 = 9 + 4 + 1 + 1. There is no way to represent 15 as the sum of three perfect squares.
sum_of_squares(16) = 1
16 itself is a perfect square.
题目分析:
真心感觉Codewars里面很喜欢出数学题,这道题感觉已经不是程序的思路,就是纯粹的数学问题,依据Lagrange’s four-square 理论,任意一个正整数都可以被拆解为4个或4个以下的完美平方数之和,同时如果n = 4^k * (8 * m + 7),那么它决不可能是3个完美正整数之和,所以就很好分析了,对于一个完美平方数或者两个完美平方数可以直接暴力判别,只需要处理好三个或四个完美平方数之和的判断即可。
最终AC的代码:
#include <cmath>
int sum_of_squares(int n) {
int j = std::sqrt(n);
if ( j * j == n ) return 1;
for ( int i = 1; i * i <= n; i++ ) {
int j = std::sqrt(n - i * i);
if ( j * j == (n - i * i) ) return 2;
}
// based on Lagrange's four-square theorem, any positive integer can be written as the sum of four or fewer perfect squares.
// and if n = 4^k * (8 * m + 7), it can't be 3 squares'sum
while ( n % 4 == 0 ) n /= 4;
if ( n % 8 == 7 ) return 4;
return 3;
}