#include #include #include #include using namespace std; long biggestBox(long H) { return 2 * H * H; } long smallestBox(long H) { long W = (H+1)/2; return H * W; } long rootXUpperBound(long x) { long y = 1; while(y*y < x) { y *= 2; } return y; } long smallestHeightWithBigEnoughBox(long N) { long hHigh = 10 * rootXUpperBound(N); long hLow = 1; while (hHigh > hLow + 1) { long hMid = (hLow + hHigh) / 2; if (biggestBox(hMid) >= N) { hHigh = hMid; } else { hLow = hMid; } } if (biggestBox(hLow) >= N) return hLow; return hHigh; } long findBest(long N) { // Find the smallest height that allows us to make a box big enough to hold // the widgets long Hmin = smallestHeightWithBigEnoughBox(N); // Computing Hmax is subtle. Instead, search until the smallest box we can // make is already more wasteful than our best solution. long bestWasted = N + 1; for (long H = Hmin;; H++) { //cout << "Testing H = " << H << endl; // Stopping rule long smallestCap = smallestBox(H); if (smallestCap > N && smallestCap - N > bestWasted) { break; } // Test this height long bestW = (N+H-1)/H; long bestWCap = H*bestW; long cap = max(bestWCap, smallestCap); //cout << " cap = " << cap << endl; bestWasted = min(bestWasted, cap - N); } return bestWasted; } void solve(istream &in) { long N; in >> N; long empty = findBest(N); cout << empty << endl; } int main(int argc, char **argv) { if (argc > 1) { ifstream in(argv[1]); if (!in) { cerr << "could not open stream" << endl; return -1; } solve(in); } else solve(cin); }