题目链接:见这里
题意:Jzzhu有一块由n*m个单位正方形组成的巧克力,他想把这块巧克力切k次,每次切割按照以下规则。
.每次只能横着或者竖着切
.每次切割应该沿着单位正方形的边缘(不能分割单位巧克力)
.每次切割只能在巧克力内部进行,且所有切法都不同
问当切完k次后,最小的巧克力面积最大是多少。
如果不存在切割方案,输出-1。
数据
n, m, k. (1 <= n, m <= 1e9; 1 <= k <= 2e9)
输入
3 4 1
6 4 2
2 3 4
输出
6
8
-1
解题思路:假设横着切了x-1次,也就是切成x份,竖着切了y-1次,也就是切成y份,
那么ans=(n/x)*(m/y),要求1<=x<=n,1<=y<=m,x+y=k+2,显然(n+m)<(k+2)时无解,考虑枚举n/x的取值,可以证明只有O(n^0.5)种,对于固定的取值,选出最大的x,此时m/y最大,同理枚举m/y的取值来更新答案。
同时我们还可以观察一下,把y = k + 2 - x 带入到 ans里面会发现,分母是一个二次函数,方程为

<nobr> y2+2y+ky </nobr>

即是开口向下的二次函数,要让原等式最大,就要让分母最小,所以我们让x 和 y分别尽量小即可,复杂度从枚举的 O(sqrt(n) + sqrt(m))降为 O(1)

代码如下:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    long long n, m, k, x, y, ans = 0;
    cin >> n >> m >> k;
    if(n + m - 2 < k){
        puts("-1");
    }
    else{
        x = min(n - 1, k);
        ans = max(ans, (n / (x + 1)) * (m / (k + 1 - x)));
        y = min(m - 1, k);
        ans = max(ans, (m / (y + 1)) * ( n / (k + 1 - y)));
        cout << ans << endl;
    }
    return 0;
}