CF#257 (Div. 2) C.

来源:互联网 发布:知乎大神 推荐 编辑:程序博客网 时间:2024/05/30 22:54
                                C. Jzzhu and Chocolate
                                                                                          time limit per test
                                                                                              1 second
                                                                                      memory limit per test
                                                                                          256 megabytes
                                                       

Jzzhu has a big rectangular chocolate bar that consists of n × m unit squares. He wants to cut this bar exactly k times. Each cut must meet the following requirements:

  • each cut should be straight (horizontal or vertical);
  • each cut should go along edges of unit squares (it is prohibited to divide any unit chocolate square with cut);
  • each cut should go inside the whole chocolate bar, and all cuts must be distinct.

The picture below shows a possible way to cut a 5 × 6 chocolate for5 times.

Imagine Jzzhu have made k cuts and the big chocolate is splitted into several pieces. Consider the smallest (by area) piece of the chocolate, Jzzhu wants this piece to be as large as possible. What is the maximum possible area of smallest piece he can get with exactly k cuts? The area of a chocolate piece is the number of unit squares in it.

Input

A single line contains three integers n, m, k(1 ≤ n, m ≤ 109; 1 ≤ k ≤ 2·109).

Output

Output a single integer representing the answer. If it is impossible to cut the big chocolatek times, print -1.

Sample test(s)
Input
3 4 1
Output
6
Input
6 4 2
Output
8
Input
2 3 4
Output
-1
Note

In the first sample, Jzzhu can cut the chocolate following the picture below:


In the second sample the optimal division looks like this:

In the third sample, it's impossible to cut a 2 × 3 chocolate4 times.






解题思路:

         最小值最大化,刚看到题被迷惑了,以为用二分或三分·······但是事实永远不想你想的那么简单,大牛们总会用各种数学转化过来。

首先,很明显如果n + m - 2 < k 的话根本切不了,直接输出-1即可。接下来是重点了,先谈谈好的情况,那就是k小于n - 1或者m - 1,

这个时候直接找最大边切(即除以k ,然后乘以另一条边)就好,这就能求出最小区域的最大面积。再下来就是有点难弄的的地方了,

如果K大于其中一条边所能切的最大边数,那它把当前这条边切完之后,就会跑去切另外一条边,此时的k值要更新,即减去刚才切完的

条数。还有的大牛列出了函数表达式,横切k1刀,纵切k2到,最后导出函数,f(x) = n * m / (k1 * k2 + k + 1) ,即最后跟k1、 k2的值有关。







AC代码:

#include <functional>#include <algorithm>#include <iostream>#include <fstream>#include <sstream>#include <iomanip>#include <numeric>#include <cstring>#include <cassert>#include <cstdio>#include <string>#include <vector>#include <bitset>#include <queue>#include <stack>#include <cmath>#include <ctime>#include <list>#include <set>#include <map>#define REP0(i, n) for (int i=0;i<int(n);++i)#define REP1(i, n) for (int i=1;i<=int(n);++i)#define FOR(i, a, b) for (int i=int(a);i<int(b);++i)#define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)using namespace std;#define REP(i, n) for (int i=0;i<int(n);++i)#define FOR(i, a, b) for (int i=int(a);i<int(b);++i)#define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)#define REP_1(i, n) for (int i=1;i<=int(n);++i)#define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)#define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)#define REP_C(i, n) for (int n____=int(n),i=0;i<n____;++i)#define FOR_C(i, a, b) for (int b____=int(b),i=a;i<b____;++i)#define DWN_C(i, b, a) for (int a____=int(a),i=b-1;i>=a____;--i)#define REP_N(i, n) for (i=0;i<int(n);++i)#define FOR_N(i, a, b) for (i=int(a);i<int(b);++i)#define DWN_N(i, b, a) for (i=int(b-1);i>=int(a);--i)#define REP_1_C(i, n) for (int n____=int(n),i=1;i<=n____;++i)#define FOR_1_C(i, a, b) for (int b____=int(b),i=a;i<=b____;++i)#define DWN_1_C(i, b, a) for (int a____=int(a),i=b;i>=a____;--i)#define REP_1_N(i, n) for (i=1;i<=int(n);++i)#define FOR_1_N(i, a, b) for (i=int(a);i<=int(b);++i)#define DWN_1_N(i, b, a) for (i=int(b);i>=int(a);--i)#define REP_C_N(i, n) for (n____=int(n),i=0;i<n____;++i)#define FOR_C_N(i, a, b) for (b____=int(b),i=a;i<b____;++i)#define DWN_C_N(i, b, a) for (a____=int(a),i=b-1;i>=a____;--i)#define REP_1_C_N(i, n) for (n____=int(n),i=1;i<=n____;++i)#define FOR_1_C_N(i, a, b) for (b____=int(b),i=a;i<=b____;++i)#define DWN_1_C_N(i, b, a) for (a____=int(a),i=b;i>=a____;--i)#define ECH(it, A) for (__typeof(A.begin()) it=A.begin(); it != A.end(); ++it)#define REP_S(it, str) for (char*it=str;*it;++it) // 用于字符串的 .. .#define REP_G(it, u) for (int it=hd[u];it;it=suc[it]) // 用于图论的 .. .#define DO(n) for ( int ____n ## __line__ = n; ____n ## __line__ -- ; )#define REP_2(i, j, n, m) REP(i, n) REP(j, m)#define REP_2_1(i, j, n, m) REP_1(i, n) REP_1(j, m)#define REP_3(i, j, k, n, m, l) REP(i, n) REP(j, m) REP(k, l)#define REP_3_1(i, j, k, n, m, l) REP_1(i, n) REP_1(j, m) REP_1(k, l)#define PB push_back#define MP(A, B) make_pair(A, B)#define PTT pair<T, T>#define fi first#define se second#define ALL(A) A.begin(), A.end()#define LLA(A) A.rbegin(), A.rend()#define CPY(A, B) memcpy(A, B, sizeof(A))#define INS(A, P, B) A.insert(A.begin() + P, B)#define ERS(A, P) A.erase(A.begin() + P)#define BSC(A, X) find(ALL(A), X) // != A.end()#define CTN(T, x) (T.find(x) != T.end())#define SZ(A) int(A.size())#define PB push_back#define MP(A, B) make_pair(A, B)#define PTT pair<T, T>#define fi first#define se second#define Display(A, n, m) {                      \    REP(i, n){                                  \        REP(j, m) cout << A[i][j] << " ";       \        cout << endl;                         \    }                                           \}#define Display_1(A, n, m) {                    \    REP_1(i, n){                                \        REP_1(j, m) cout << A[i][j] << " ";     \        cout << endl;                         \    }                                           \}typedef long long LL;typedef double DB;typedef unsigned UINT;typedef unsigned long long ULL;const int dx[] = {-1, 0, 1, 0};const int dy[] = {0, 1, 0, -1};const int MOD = 1000000007;const int INF = 0x3f3f3f3f;const LL INFF = 1LL << 60;const DB EPS = 1e-9;const DB OO = 1e15;const DB PI = acos(-1.0); //M_PI;__int64 n , m , k , t , ans;int main(){    while(~scanf("%I64d%I64d%I64d",&n,&m,&k))    {        if(n + m - 2 < k)        {            printf("-1\n");            continue;        }                    if(k < n - 1)            ans = max(ans , n / (k + 1) * m);        if(k < m - 1)            ans = max(ans , m / (k + 1) * n);        if(k >= n - 1)            ans = max(ans , m / ( k - n + 2));        if(k >= m - 1)            ans = max(ans , n / (k - m + 2));        printf("%I64d\n",ans);    }}




0 0
原创粉丝点击