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; } };