Sum of a Square and a Cube
Find the sum of the five smallest palindromic numbers that can each be expressed as the sum of a square and a cube (a^2 + b^3 with a >= 1, b >= 1) in exactly 4 different ways.
Problem Statement
This archive keeps the full statement, math, and original media on the page.
Many numbers can be expressed as the sum of a square and a cube. Some of them in more than one way.
Consider the palindromic numbers that can be expressed as the sum of a square and a cube, both greater
than \(1\), in
For example, \(5229225\) is a palindromic number and it can be expressed in exactly \(4\) different ways:
\(2285^2 + 20^3\)
\(2223^2 + 66^3\)
\(1810^2 + 125^3\)
\(1197^2 + 156^3\)
Find the sum of the five smallest such palindromic numbers.
Problem 348: Sum of a Square and a Cube
Mathematical Foundation
Theorem 1 (Representation Count). For a positive integer , define
We seek palindromic with .
Proof (well-definedness). For fixed , the constraint gives , so ranges over finitely many values. For each , at most one satisfies (namely if this is a positive integer). Hence is finite and computable.
Lemma 1 (Palindrome Structure). A -digit palindrome is determined by its first digits. The number of -digit palindromes is (the leading digit is nonzero).
Proof. A palindrome satisfies . The free digits are with and for .
Lemma 2 (Search Bound). Since we need only 5 palindromes, and empirically the answer involves palindromes below , we search palindromes up to . For each palindrome :
- ranges from 1 to
- Checking whether is a perfect square costs via integer square root
Proof. implies . Computing and verifying its square equals is arithmetic.
Editorial
We enumerate the admissible parameter range, discard candidates that violate the derived bounds or arithmetic constraints, and update the final set or total whenever a candidate passes the acceptance test.
Pseudocode
results = []
for d = 1, 2, 3, ...: // number of digits
for each d-digit palindrome n (in increasing order):
count = 0
For b from 1 to floor(n^(1/3)):
remainder = n - b^3
If remainder <= 0 then stop this loop
a = isqrt(remainder)
If a * a == remainder and a >= 1 then
count += 1
If count > target_count then stop this loop
If count == target_count then
results.append(n)
If len(results) == num_needed then
Return sum(results)
Complexity Analysis
- Time: where is the number of palindromes checked and is the search bound. With palindromes below and , total is .
- Space: beyond storing the results (palindromes are generated on the fly).
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
bool is_palindrome(long long n) {
string s = to_string(n);
string r = s;
reverse(r.begin(), r.end());
return s == r;
}
int main() {
// We search palindromes up to some limit
const long long LIMIT = 1000000000LL; // 10^9 should be enough
// For each palindrome, count ways to write it as a^2 + b^3
// We'll generate palindromes and check each
vector<long long> results;
// Generate palindromes in order by iterating through possible values
// Instead, iterate all numbers and check palindrome + count
// More efficient: generate palindromes directly
// Generate palindromes by building from half
vector<long long> palindromes;
// Single digit palindromes
for (int d = 1; d <= 9; d++) palindromes.push_back(d);
// Generate multi-digit palindromes
for (int half_len = 1; half_len <= 5; half_len++) {
long long start = 1;
for (int i = 1; i < half_len; i++) start *= 10;
long long end_ = start * 10;
// Even length: half_len * 2
for (long long h = start; h < end_; h++) {
string s = to_string(h);
string r = s;
reverse(r.begin(), r.end());
long long p = stoll(s + r);
if (p < LIMIT) palindromes.push_back(p);
}
// Odd length: half_len + 1 + half_len - but we handle it as:
// left half (half_len digits) + middle digit + reversed left half
// Actually simpler: for odd length 2*half_len+1
for (long long h = start; h < end_; h++) {
string s = to_string(h);
string r = s.substr(0, s.size() - 1);
reverse(r.begin(), r.end());
long long p = stoll(s + r);
if (p < LIMIT) palindromes.push_back(p);
}
}
sort(palindromes.begin(), palindromes.end());
palindromes.erase(unique(palindromes.begin(), palindromes.end()), palindromes.end());
for (long long pal : palindromes) {
if (pal < 2) continue; // need a>=1, b>=1, so min is 1+1=2
int count = 0;
for (long long b = 1; b * b * b < pal; b++) {
long long rem = pal - b * b * b;
long long a = (long long)round(sqrt((double)rem));
if (a >= 1 && a * a == rem) {
count++;
}
}
if (count == 4) {
results.push_back(pal);
if (results.size() == 5) break;
}
}
long long sum = 0;
for (long long v : results) sum += v;
cout << sum << endl;
return 0;
}
import math
def solve():
LIMIT = 10**9
def generate_palindromes(limit):
"""Generate all palindromes up to limit in sorted order."""
pals = []
# Single digit
for d in range(1, 10):
pals.append(d)
# Multi-digit: generate by half
for length in range(2, 11):
half_len = (length + 1) // 2
start = 10 ** (half_len - 1)
end = 10 ** half_len
for h in range(start, end):
s = str(h)
if length % 2 == 0:
p = int(s + s[::-1])
else:
p = int(s + s[-2::-1])
if p >= limit:
break
pals.append(p)
pals.sort()
return pals
palindromes = generate_palindromes(LIMIT)
results = []
for pal in palindromes:
if pal < 2:
continue
count = 0
b = 1
while b ** 3 < pal:
rem = pal - b ** 3
a = int(math.isqrt(rem))
if a >= 1 and a * a == rem:
count += 1
b += 1
if count == 4:
results.append(pal)
if len(results) == 5:
break
print(sum(results))
if __name__ == "__main__":
solve()