2辺の長さを決める。よくあるアレ。
入力が大きいので、とりあえず2辺を決める方向で考える。
大きい方に合わせて残りの1辺の長さを決めて、小さい方で帳尻を合わせてみる。
問題は、小さい方をキューブのどの面の方向に並べるか。
i <= j <= k のとき、
A. (i + 1) * j * k
B. i * (j + 1) * k
C. i * j * (k + 1)
格方向へ1だけ大きくした場合、 i * j だけ増加する C が小さそう。
大きくする量が 1 より大きくても同じ事が言えそうな気がする。
小さい方の残りは、ある1つの面だけを必要なだけ伸ばして対処してみる。
サンプル合う。投げる。通る。
class CubePacking {
public:
int getMinimumVolume(int Ns, int Nb, int L)
{
const lli U = INT_MAX;
lli mn = U;
for (lli i = 1; (i * i <= double(U) / i); ++i) {
for (lli j = 1; (j * j <= double(U) / i); ++j) {
lli k;
lli a = i / L;
lli b = j / L;
lli B = a * b;
if (B <= 0) continue;
k = ((Nb / B) + (bool)(Nb % B)) * L;
lli c = k / L;
lli d = (a * b * c) - Nb;
if (d < 0) continue;
lli rest = Ns - ((i * j * k) - (L * L * L) * Nb);
if (0 < rest) {
lli e = i * j;
k += (rest / e) + (bool)(rest % e);
}
mn = min(mn, i * j * k);
}
}
return mn;
}
};