Cuboid Layers
The minimum number of cubes to cover every visible face on a cuboid measuring 3 x 2 x 1 is twenty-two. If we then add a second layer to this solid it would require forty-six cubes, the third layer...
Problem Statement
This archive keeps the full statement, math, and original media on the page.
The minimum number of cubes to cover every visible face on a cuboid measuring \(3 \times 2 \times 1\) is twenty-two.

If we then add a second layer to this solid it would require forty-six cubes to cover every visible face, the third layer would require seventy-eight cubes, and the fourth layer would require one-hundred and eighteen cubes to cover every visible face.
However, the first layer on a cuboid measuring \(5 \times 1 \times 1\) also requires twenty-two cubes; similarly the first layer on cuboids measuring \(5 \times 3 \times 1\), \(7 \times 2 \times 1\), and \(11 \times 1 \times 1\) all contain forty-six cubes.
We shall define \(C(n)\) to represent the number of cuboids that contain \(n\) cubes in one of its layers. So \(C(22) = 2\), \(C(46) = 4\), \(C(78) = 5\), and \(C(118) = 8\).
It turns out that \(154\) is the least value of \(n\) for which \(C(n) = 10\).
Find the least value of \(n\) for which \(C(n) = 1000\).
Problem 126: Cuboid Layers
Mathematical Development
Theorem 1 (Layer formula). For a cuboid with dimensions (), the number of cubes in the -th layer () is
Proof. The total volume enclosed by layers around an cuboid (including the cuboid itself) is
where the subtraction accounts for the hollow interior. The number of cubes in layer alone is
Expanding:
Let . Then equals:
Expanding both products and subtracting, collecting terms in powers of :
Verification: For : , which is the surface area of the cuboid. For : . For : . Both match the problem statement.
Lemma 1 (Monotonicity in ). For fixed , is strictly increasing in .
Proof. for all and positive dimensions.
Lemma 2 (Enumeration bounds). To find all with :
- : from while (minimum layer for cube ).
- : from while .
- : from while (the value).
- : from while .
Proof. For with : , so gives , which is weaker than (obtained from with ). The other bounds follow from (the minimum).
Editorial
Once the closed formula for the -th layer is available, the problem becomes a counting task: how many tuples produce each layer size ? Because the layer size is monotone in every parameter, the search can be bounded very tightly. The constraints avoid duplicate cuboids, and for each fixed cuboid the layer index is increased only until the formula exceeds the global limit.
The implementation maintains a frequency array telling how many cuboids realize a layer of size . It enumerates every feasible ordered cuboid, walks through its successive layers, increments the corresponding counts, and finally scans upward for the first value where the count reaches 1000.
Pseudocode
Choose a search limit large enough to contain the first answer.
Initialize a counting array C over all layer sizes up to that limit.
Enumerate side lengths a, b, c with a <= b <= c, stopping each loop as soon as the first layer is already too large.
For each cuboid:
Increase the layer index k from 1 upward.
Evaluate the layer-size formula.
If the value exceeds the search limit, stop increasing k for this cuboid.
Otherwise increment C at that layer size.
Scan the counting array from small to large and return the first n with C(n) = 1000.
Complexity Analysis
- Time: The four nested loops enumerate all tuples with . The number of such tuples is empirically. Total: .
- Space: for the counting array .
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
int main() {
const int LIMIT = 20000;
vector<int> C(LIMIT + 1, 0);
// f(a,b,c,k) = 2(ab+bc+ac) + 4(a+b+c)(k-1) + 4(k-1)(k-2)
for (int a = 1; 2LL * a * a <= LIMIT; a++) {
for (int b = a; 2LL * (a * b + b * b) <= LIMIT; b++) {
for (int c = b; 2LL * ((long long)a * b + (long long)b * c + (long long)a * c) <= LIMIT; c++) {
long long base = 2LL * (a * b + b * c + a * c);
long long edge = 4LL * (a + b + c);
for (int k = 1; ; k++) {
long long val = base + edge * (k - 1) + 4LL * (k - 1) * (k - 2);
if (val > LIMIT) break;
C[(int)val]++;
}
}
}
}
for (int n = 1; n <= LIMIT; n++) {
if (C[n] == 1000) {
cout << n << endl;
return 0;
}
}
return 0;
}
"""
Problem 126: Cuboid Layers
Find the least n for which C(n) = 1000, where C(n) counts
the number of cuboids that have exactly n cubes in one of its layers.
Layer formula: f(a,b,c,k) = 2(ab+bc+ac) + 4(a+b+c)(k-1) + 4(k-1)(k-2)
"""
def solve(target=1000):
LIMIT = 20000
C = [0] * (LIMIT + 1)
a = 1
while 2 * a * a <= LIMIT:
b = a
while 2 * (a * b + b * b) <= LIMIT:
c = b
while 2 * (a * b + b * c + a * c) <= LIMIT:
base = 2 * (a * b + b * c + a * c)
edge = 4 * (a + b + c)
k = 1
while True:
val = base + edge * (k - 1) + 4 * (k - 1) * (k - 2)
if val > LIMIT:
break
C[val] += 1
k += 1
c += 1
b += 1
a += 1
for n in range(1, LIMIT + 1):
if C[n] == target:
return n
return -1
def visualize():
"""Optional visualization of C(n) distribution."""
if __name__ == "__main__":
answer = solve()
assert answer == 18522
print(answer)