Beta Round #66-A: The Elder Trolls IV: Oblivon
keyword
数学 C++
問題概要
3辺がX,Y,Z(<10^6)の豆腐にK回まで整数座標のところで包丁を入れられる。最大でいくつのブロックができるか求める問題。
解法
和が一定のときに積を最大にする問題。当然、バランスが取れているほど大きくなる。一辺をいくつに切るかで全探索して、残りは半分に近い大きさで切る、という方法で通った。
もっと賢い(分かりやすい)方法もある。X,Y,Z軸でいくつにわけるかをx,y,zと置いて1で初期化し、Kが残っていて、かつ上限を越えない限り順番にincしていく。
#include <iostream> using namespace std; typedef long long int64; int64 X,Y,Z,K; int64 solve(){ int64 ans = 1; for(int64 a=1; a<=X && (a-1)<=K; a++){ int64 tmp = a; int64 res = K-a+1; if((Y-1) + (Z-1) <= res){ ans = max(ans, tmp * Y * Z); } if((Y-1) <= (res+1)/2){ ans = max(ans, tmp * Y * min(Z, res - (Y - 1))); } if((Z-1) <= (res+1)/2){ ans = max(ans, tmp * Z * min(Y, res - (Z - 1))); } ans = max(ans, tmp * min(Y,res/2+1) * min(Z,res - res/2 + 1)); ans = max(ans, tmp); } return ans; } int main(){ cin >> X >> Y >> Z >> K; int64 ans = 0; ans = max(ans, solve()); swap(X,Y); ans = max(ans, solve()); swap(Y,Z); ans = max(ans, solve()); swap(Z,X); ans = max(ans,solve()); swap(X,Y); ans = max(ans, solve()); swap(Y,Z); ans = max(ans, solve()); cout << ans << endl; return 0; }