Problem:
F - 土地相続
Problem Statement
ある $N$ 人の兄弟は親の遺産相続の話し合いをしていた．
彼らの親の残した莫大な遺産の中には広大な土地も含まれていた．
その土地は南北に $H$ km, 東西に $W$ km に広がる長方形の形をしている．
この土地は 1 km 四方の区画単位で管理されており，
土地の北端から $i$ 〜 $i+1$ km かつ西端から $j$ 〜 $j+1$ km の範囲にある 1 km 四方の区画を区画 $(i, j)$ と呼ぶ．
（$i$, $j$ は $0 \leq i < H$, $0 \leq j < W$ を満たす整数である．）
土地の価格は区画ごとに決まっており，区画 $(i, j)$ の価格は $a_{i, j}$ で表される．
兄弟は次のように土地を分けて相続することにした．
$N$ 人の兄弟それぞれが区画をいくつか選び相続する．
各兄弟が相続する土地が 1 つの長方形を成すように区画を選ばなければならない．
$N$ 人の兄弟が相続する土地は重なってはならない．
誰も相続しない区画があってもよい．誰も相続しない区画は放棄される．
ある人が相続する土地の範囲に含まれる区画の価格の和をその土地の価格と呼ぶ．
兄弟は，各々が相続する土地の価格がなるべく公平になるように土地を分けたい．
あなたの仕事は， $N$ 人の中で相続する土地の価格が
最も低い人の土地の価格を最大にするような土地の分け方を考えることである．
そのように土地を分けた時の，相続する土地の価格が最も低い人の土地の価格を答えるプログラムを作成せよ．
Input
入力は以下のような形式で与えられる．
$H$ $W$ $N$
$a_{0,0}$ $a_{0,1}$ ... $a_{0,W-1}$
...
$a_{H-1,0}$ $a_{H-1,1}$ ... $a_{H-1,W-1}$
$H$, $W$ $(2 \leq H,W \leq 200)$ は遺産の土地の南北の長さと東西の長さをそれぞれ表す．
$N$ $(2 \leq N \leq 4)$ は土地を相続する兄弟の人数を表す．
$a_{i, j}$ $(0 \leq a_{i,j} \leq 10^4)$ は区画 $(i, j)$ の価格を表す．
Output
相続する土地の価格が最も低い人の土地の価格を最大にするように分けた時の，
最も低い土地の価格を 1 行で出力せよ．
Sample Input 1
3 3 2
1 2 2
3 1 0
0 4 3
Output for the Sample Input 1
7
図のように分けるのが最適である．
Sample Input 2
3 3 2
0 1 0
1 1 1
0 1 0
Output for the Sample Input 2
1
Sample Input 3
2 5 3
8 3 0 5 6
2 5 2 5 2
Output for the Sample Input 3
11
Sample Input 4
3 3 4
3 3 4
3 3 4
3 3 4
Output for the Sample Input 4
7
Sample Input 5
4 4 4
2 2 2 2
2 1 2 1
2 2 2 2
2 1 2 1
Output for the Sample Input 5
7

Submitted solutions:

code_snippet: // AOJ 2743 Land Inheritance
// 2025.5.16

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(ll n) {
	int i; char b[30];
	if (!n) pc('0');
	else {
		i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

int H, W, N;
ll S[201][201];
ll A[200][200];
unordered_map<ull, ll> dp;

inline ll sumRect(int lx, int ly, int rx, int ry) {
    return S[rx][ry] - S[lx][ry] - S[rx][ly] + S[lx][ly];
}

ll rec(int n, int lx, int ly, int rx, int ry) {
    ull key = ((ull)n << 32)
                           | ((ull)lx << 24)
                           | ((ull)ly << 16)
                           | ((ull)rx << 8)
                           | (ull)ry;
    auto it = dp.find(key);
    if (it != dp.end()) return it->second;

    ll ans = 0;
    if (n == 2) {
        ll total = sumRect(lx, ly, rx, ry);
        {
            int ok = lx, ng = rx;
            while (ng - ok > 1) {
                int md = (ok + ng) >> 1;
                if (sumRect(lx, ly, md, ry) * 2 < total) ok = md;
                else ng = md;
            }
            ans = max(ans, min(sumRect(lx, ly, ok, ry), sumRect(ok, ly, rx, ry)));
            ans = max(ans, min(sumRect(lx, ly, ok+1, ry), sumRect(ok+1, ly, rx, ry)));
        }
        {
            int ok = ly, ng = ry;
            while (ng - ok > 1) {
                int md = (ok + ng) >> 1;
                if (sumRect(lx, ly, rx, md) * 2 < total) ok = md;
                else ng = md;
            }
            ans = max(ans, min(sumRect(lx, ly, rx, ok), sumRect(lx, ok, rx, ry)));
            ans = max(ans, min(sumRect(lx, ly, rx, ok+1), sumRect(lx, ok+1, rx, ry)));
        }
    } else if (n == 3) {
        for (int x = lx + 1; x < rx; x++) {
            ll s1 = sumRect(lx, ly, x, ry);
            ll s2 = rec(2, x, ly, rx, ry);
            ans = max(ans, min(s1, s2));
            s1 = sumRect(x, ly, rx, ry);
            s2 = rec(2, lx, ly, x, ry);
            ans = max(ans, min(s1, s2));
        }
        for (int y = ly + 1; y < ry; y++) {
            ll s1 = sumRect(lx, ly, rx, y);
            ll s2 = rec(2, lx, y, rx, ry);
            ans = max(ans, min(s1, s2));
            s1 = sumRect(lx, y, rx, ry);
            s2 = rec(2, lx, ly, rx, y);
            ans = max(ans, min(s1, s2));
        }
    } else {
        for (int x = lx + 1; x < rx; x++) {
            ll s1 = sumRect(lx, ly, x, ry);
            ll s2 = rec(3, x, ly, rx, ry);
            ans = max(ans, min(s1, s2));
            s1 = sumRect(x, ly, rx, ry);
            s2 = rec(3, lx, ly, x, ry);
            ans = max(ans, min(s1, s2));
            ll r1 = rec(2, lx, ly, x, ry);
            ll r2 = rec(2, x,  ly, rx, ry);
            ans = max(ans, min(r1, r2));
        }
        for (int y = ly + 1; y < ry; y++) {
            ll s1 = sumRect(lx, ly, rx, y);
            ll s2 = rec(3, lx, y, rx, ry);
            ans = max(ans, min(s1, s2));
            s1 = sumRect(lx, y, rx, ry);
            s2 = rec(3, lx, ly, rx, y);
            ans = max(ans, min(s1, s2));
            ll r1 = rec(2, lx, ly, rx, y);
            ll r2 = rec(2, lx, y,  rx, ry);
            ans = max(ans, min(r1, r2));
        }
        ll ok = 0, ng = sumRect(lx, ly, rx, ry) + 1;
        while (ng - ok > 1) {
            ll md = (ok + ng) >> 1;
            bool make = false;
            for (int x = lx + 1; x < rx && !make; x++) {
                int bx = lx, tx = x, by = ly, ty = ly;
                while (ty <= ry && sumRect(bx, by, tx, ty) < md) ty++;
                if (ty > ry) continue;
                int mm = ty;
                bx = lx; tx = lx; by = ty; ty = ry;
                while (tx <= rx && sumRect(bx, by, tx, ty) < md) tx++;
                if (tx > rx) continue;
                by = ry; ty = ry; bx = max(x, tx); tx = rx;
                while (by >= ly && sumRect(bx, by, tx, ty) < md) by--;
                if (by < ly) continue;
                by = min(by, mm);
                if (sumRect(x, ly, rx, by) < md) continue;
                make = true;
            }
            for (int y = ly + 1; y < ry && !make; y++) {
                int bx = lx, tx = lx, by = ly, ty = y;
                while (tx <= rx && sumRect(bx, by, tx, ty) < md) tx++;
                if (tx > rx) continue;
                int mm = tx;
                by = ly; ty = ly; bx = tx; tx = rx;
                while (ty <= ry && sumRect(bx, by, tx, ty) < md) ty++;
                if (ty > ry) continue;
                bx = rx; tx = rx; by = max(y, ty); ty = ry;
                while (bx >= lx && sumRect(bx, by, tx, ty) < md) bx--;
                if (bx < lx) continue;
                bx = min(bx, mm);
                if (sumRect(lx, y, bx, ry) < md) continue;
                make = true;
            }
            if (make) ok = md; else ng = md;
        }
        ans = max(ans, ok);
    }
    return dp[key] = ans;
}

int main(){
    H = Cin(), W = Cin(), N = Cin();

    for(int i=0;i<H;i++){
        for(int j=0;j<W;j++){
            cin >> A[i][j];
            S[i+1][j+1] = A[i][j];
        }
    }
    for(int i=0;i<=H;i++){
        for(int j=0;j<=W;j++){
            if(i>0) S[i][j] += S[i-1][j];
            if(j>0) S[i][j] += S[i][j-1];
            if(i>0&&j>0) S[i][j] -= S[i-1][j-1];
        }
    }
    dp.reserve(65536);
    Cout(rec(N, 0, 0, H, W));
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 12168
final_rank: 4

code_snippet: // AOJ #2743 Land Inheritance
// 2025.2.23

#include <bits/stdc++.h>
using namespace std;

int H, W, N;
vector<vector<int>> grid;
vector<vector<int>> ps;

void pre(){
    ps.assign(H+1, vector<int>(W+1, 0));
    for (int i = 0; i < H; i++){
        for (int j = 0; j < W; j++){
            ps[i+1][j+1] = grid[i][j] + ps[i][j+1] + ps[i+1][j] - ps[i][j];
        }
    }
}

int rect(int r1, int c1, int r2, int c2){
    return ps[r2][c2] - ps[r1][c2] - ps[r2][c1] + ps[r1][c1];
}

bool check1(int T, int r1, int c1, int r2, int c2){
    return rect(r1, c1, r2, c2) >= T;
}

bool check2(int T, int r1, int c1, int r2, int c2){
    for (int r = r1+1; r < r2; r++)
        if(rect(r1, c1, r, c2) >= T && rect(r, c1, r2, c2) >= T) return true;

    for (int c = c1+1; c < c2; c++)
        if(rect(r1, c1, r2, c) >= T && rect(r1, c, r2, c2) >= T) return true;

    return false;
}

bool check3(int T, int r1, int c1, int r2, int c2){
    for (int rA = r1+1; rA <= r2-2; rA++){
        if(rect(r1, c1, rA, c2) < T) continue;
        for (int rB = rA+1; rB <= r2-1; rB++){
            if(rect(rA, c1, rB, c2) < T) continue;
            if(rect(rB, c1, r2, c2) >= T) return true;
        }
    }
    for (int cA = c1+1; cA <= c2-2; cA++){
        if(rect(r1, c1, r2, cA) < T) continue;
        for (int cB = cA+1; cB <= c2-1; cB++){
            if(rect(r1, cA, r2, cB) < T) continue;
            if(rect(r1, cB, r2, c2) >= T) return true;
        }
    }
    for (int r = r1+1; r < r2; r++){
        if(rect(r1, c1, r, c2) < T) continue;
        for (int c = c1+1; c < c2; c++){
            if(rect(r, c1, r2, c) >= T && rect(r, c, r2, c2) >= T)
                return true;
        }
    }
    for (int r = r1+1; r < r2; r++){
        if(rect(r, c1, r2, c2) < T) continue;
        for (int c = c1+1; c < c2; c++){
            if(rect(r1, c1, r, c) >= T && rect(r1, c, r, c2) >= T)
                return true;
        }
    }
    for (int c = c1+1; c < c2; c++){
        if(rect(r1, c1, r2, c) < T) continue;
        for (int r = r1+1; r < r2; r++){
            if(rect(r1, c, r, c2) >= T && rect(r, c, r2, c2) >= T)
                return true;
        }
    }
    for (int c = c1+1; c < c2; c++){
        if(rect(r1, c, r2, c2) < T) continue;
        for (int r = r1+1; r < r2; r++){
            if(rect(r1, c1, r, c) >= T && rect(r, c1, r2, c) >= T)
                return true;
        }
    }
    return false;
}

bool check4(int T, int r1, int c1, int r2, int c2){
    for (int rA = r1+1; rA <= r2-3; rA++){
        if(rect(r1, c1, rA, c2) < T) continue;
        for (int rB = rA+1; rB <= r2-2; rB++){
            if(rect(rA, c1, rB, c2) < T) continue;
            for (int rC = rB+1; rC <= r2-1; rC++){
                if(rect(rB, c1, rC, c2) < T) continue;
                if(rect(rC, c1, r2, c2) >= T) return true;
            }
        }
    }
    for (int cA = c1+1; cA <= c2-3; cA++){
        if(rect(r1, c1, r2, cA) < T) continue;
        for (int cB = cA+1; cB <= c2-2; cB++){
            if(rect(r1, cA, r2, cB) < T) continue;
            for (int cC = cB+1; cC <= c2-1; cC++){
                if(rect(r1, cB, r2, cC) < T) continue;
                if(rect(r1, cC, r2, c2) >= T) return true;
            }
        }
    }
    for (int r = r1+1; r < r2; r++){
        for (int cTop = c1+1; cTop < c2; cTop++){
            if(rect(r1, c1, r, cTop) < T) continue;
            if(rect(r1, cTop, r, c2) < T) continue;
            for (int cBot = c1+1; cBot < c2; cBot++){
                if(rect(r, c1, r2, cBot) < T) continue;
                if(rect(r, cBot, r2, c2) < T) continue;
                return true;
            }
        }
    }
    for (int c = c1+1; c < c2; c++){
        for (int rLeft = r1+1; rLeft < r2; rLeft++){
            if(rect(r1, c1, rLeft, c) < T) continue;
            if(rect(rLeft, c1, r2, c) < T) continue;
            for (int rRight = r1+1; rRight < r2; rRight++){
                if(rect(r1, c, rRight, c2) < T) continue;
                if(rect(rRight, c, r2, c2) < T) continue;
                return true;
            }
        }
    }
    for (int r = r1+1; r < r2; r++){
        if(rect(r1, c1, r, c2) < T) continue;
        if(check3(T, r, c1, r2, c2)) return true;
    }
    for (int r = r1+1; r < r2; r++){
        if(rect(r, c1, r2, c2) < T) continue;
        if(check3(T, r1, c1, r, c2)) return true;
    }
    for (int c = c1+1; c < c2; c++){
        if(rect(r1, c1, r2, c) < T) continue;
        if(check3(T, r1, c, r2, c2)) return true;
    }
    for (int c = c1+1; c < c2; c++){
        if(rect(r1, c, r2, c2) < T) continue;
        if(check3(T, r1, c1, r2, c)) return true;
    }
    return false;
}

bool check(int T){
    if(N == 1) return check1(T, 0, 0, H, W);
    if(N == 2) return check2(T, 0, 0, H, W);
    if(N == 3) return check3(T, 0, 0, H, W);
    if(N == 4) return check4(T, 0, 0, H, W);
    return false;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> H >> W >> N;
    grid.assign(H, vector<int>(W, 0));
    int total = 0;
    for (int i = 0; i < H; i++){
        for (int j = 0; j < W; j++){
            cin >> grid[i][j];
            total += grid[i][j];
        }
    }
    pre();

    int lo = 0, hi = total, ans = 0;
    while(lo <= hi){
        int mid = (lo + hi) / 2;
        if(check(mid)){
            ans = mid;
            lo = mid + 1;
        } else hi = mid - 1;
    }
    cout << ans << endl;
    return 0;
}
accuracy: 0.8181818181818182
time_ms: 280
memory_kb: 3768
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;

int H, W, N, K;
long long a[205][205];
long long c[205][205];

long long f(int u, int d, int l, int r) {
  return c[d + 1][r + 1] + c[u][l] - c[d + 1][l] - c[u][r + 1];
}

int bin_ho(int u, int d, int l, int r) {
  assert(u < d);
  if(u + 1 == d) return u;
  int ok = u, ng = d;
  while(ok + 1 < ng) {
    int k = (ok + ng) / 2;
    if(f(u, k, l, r) < f(k + 1, d, l, r)) ok = k;
    else ng = k;
  }
  if(ng == d) return ok;
  const long long val_ok = min(f(u, ok, l, r), f(ok + 1, d, l, r));
  const long long val_ng = min(f(u, ng, l, r), f(ng + 1, d, l, r));
  return (val_ok > val_ng ? ok : ng);
}

int bin_ve(int u, int d, int l, int r) {
  assert(l < r);
  if(l + 1 == r) return l;
  int ok = l, ng = r;
  while(ok + 1 < ng) {
    int k = (ok + ng) / 2;
    if(f(u, d, l, k) < f(u, d, k + 1, r)) ok = k;
    else ng = k;
  }
  if(ng == r) return ok;
  const long long val_ok = min(f(u, d, l, ok), f(u, d, ok + 1, r));
  const long long val_ng = min(f(u, d, l, ng), f(u, d, ng + 1, r));
  return (val_ok > val_ng ? ok : ng);
}

long long div_opt(int u, int d, int l, int r) {
  long long ret = 0;
  if(u < d) {
    const int m = bin_ho(u, d, l, r);
    ret = max(ret, min(f(u, m, l, r), f(m + 1, d, l, r)));
  }
  if(l < r) {
    const int m = bin_ve(u, d, l, r);
    ret = max(ret, min(f(u, d, l, m), f(u, d, m + 1, r)));
  }
  return ret;
}

void rotate()
{
  for (int i = 0; i <= K; i++) {
    for (int j = 0; j <= K; j++) {
      c[i][j] = 0;
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      c[W - 1 - j][i] = a[i][j];
    }
  }
  for (int i = 0; i <= K; i++) {
    for (int j = 0; j <= K; j++) {
      a[i][j] = 0;
    }
  }
  swap(H, W);
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      a[i][j] = c[i][j];
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      c[i + 1][j + 1] = a[i][j];
    }
  }
  for(int i = 0; i <= H; i++) {
    for(int j = 1; j <= W; j++) {
      c[i][j] += c[i][j - 1];
    }
  }
  for(int j = 0; j <= W; j++) {
    for(int i = 1; i <= H; i++) {
      c[i][j] += c[i - 1][j];
    }
  }
}

int main() {
  cin >> H >> W >> N;
  K = max(H, W);
  for(int i = 0; i <= K; i++) {
    for(int j = 0; j <= K; j++) {
      a[i][j] = 0;
    }
  }
  for(int i = 0; i < H; i++) {
    for(int j = 0; j < W; j++) {
      cin >> a[i][j];
    }
  }
  long long ans = 0;
  if(N == 2) {
    rotate();
    for(int i = 0; i < H - 1; i++) {
      ans = max(ans, min(f(0, i, 0, W - 1), f(i + 1, H - 1, 0, W - 1)));
    }
    for(int j = 0; j < W - 1; j++) {
      ans = max(ans, min(f(0, H - 1, 0, j), f(0, H - 1, j + 1, W - 1)));
    }
    cout << ans << endl;
    return 0;
  }
  for(int _t = 0; _t < 4; _t++) {
    rotate();
    // 横2本
    for(int i = 0; i < H; i++) {
      for(int j = i + 1; j + 1 < H; j++) {
        const int k = H - 1;
        if(N == 3) {
          const long long cur = min(f(0, i, 0, W - 1), min(f(i + 1, j, 0, W - 1), f(j + 1, k, 0, W - 1)));
          ans = max(ans, cur);
          continue;
        }
        {
          const long long val_org = min(f(i + 1, j, 0, W - 1), f(j + 1, k, 0, W - 1));
          ans = max(ans, min(val_org, div_opt(0, i, 0, W - 1)));
        }
        {
          const long long val_org = min(f(0, i, 0, W - 1), f(j + 1, k, 0, W - 1));
          ans = max(ans, min(val_org, div_opt(i + 1, j, 0, W - 1)));
        }
        {
          const long long val_org = min(f(i + 1, j, 0, W - 1), f(0, i, 0, W - 1));
          ans = max(ans, min(val_org, div_opt(j + 1, k, 0, W - 1)));
        }
      }
    }
    // 縦横
    for(int i = 0; i < H; i++) {
      for(int j = 0; j + 1 < W; j++) {
        const int k = H - 1;
        if(N == 3) {
          const long long cur = min(f(0, i, 0, W - 1), min(f(i + 1, k, 0, j), f(i + 1, k, j + 1, W - 1)));
          ans = max(ans, cur);
          continue;
        }
        {
          const long long val_org =  min(f(i + 1, k, 0, j), f(i + 1, k, j + 1, W - 1));
          ans = max(ans, min(val_org, div_opt(0, i, 0, W - 1)));
        }
        {
          const long long val_org = min(f(0, i, 0, W - 1), f(i + 1, k, j + 1, W - 1));
          ans = max(ans, min(val_org, div_opt(i + 1, k, 0, j)));
        }
        {
          const long long val_org = min(f(i + 1, k, 0, j), f(0, i, 0, W - 1));
          ans = max(ans, min(val_org, div_opt(i + 1, k, j + 1, W - 1)));
        }
      }
    }
  }
  cout << ans << endl;
}
accuracy: 0.8181818181818182
time_ms: 60
memory_kb: 4092
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;

int H, W, N, K;
long long a[205][205];
long long c[205][205];

long long f(int u, int d, int l, int r) {
  return c[d + 1][r + 1] + c[u][l] - c[d + 1][l] - c[u][r + 1];
}

int bin_ho(int u, int d, int l, int r) {
  assert(u < d);
  if(u + 1 == d) return u;
  int ok = u, ng = d;
  while(ok + 1 < ng) {
    int k = (ok + ng) / 2;
    if(f(u, k, l, r) < f(k + 1, d, l, r)) ok = k;
    else ng = k;
  }
  if(ng == d) return ok;
  const long long val_ok = min(f(u, ok, l, r), f(ok + 1, d, l, r));
  const long long val_ng = min(f(u, ng, l, r), f(ng + 1, d, l, r));
  return (val_ok > val_ng ? ok : ng);
}

int bin_ve(int u, int d, int l, int r) {
  assert(l < r);
  if(l + 1 == r) return l;
  int ok = l, ng = r;
  while(ok + 1 < ng) {
    int k = (ok + ng) / 2;
    if(f(u, d, l, k) < f(u, d, k + 1, r)) ok = k;
    else ng = k;
  }
  if(ng == r) return ok;
  const long long val_ok = min(f(u, d, l, ok), f(u, d, ok + 1, r));
  const long long val_ng = min(f(u, d, l, ng), f(u, d, ng + 1, r));
  return (val_ok > val_ng ? ok : ng);
}

long long div_opt(int u, int d, int l, int r) {
  long long ret = 0;
  if(u < d) {
    const int m = bin_ho(u, d, l, r);
    ret = max(ret, min(f(u, m, l, r), f(m + 1, d, l, r)));
  }
  if(l < r) {
    const int m = bin_ve(u, d, l, r);
    ret = max(ret, min(f(u, d, l, m), f(u, d, m + 1, r)));
  }
  return ret;
}

void rotate()
{
  for (int i = 0; i <= K; i++) {
    for (int j = 0; j <= K; j++) {
      c[i][j] = 0;
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      c[W - 1 - j][i] = a[i][j];
    }
  }
  for (int i = 0; i <= K; i++) {
    for (int j = 0; j <= K; j++) {
      a[i][j] = 0;
    }
  }
  swap(H, W);
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      a[i][j] = c[i][j];
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      c[i + 1][j + 1] = a[i][j];
    }
  }
  for(int i = 0; i <= H; i++) {
    for(int j = 1; j <= W; j++) {
      c[i][j] += c[i][j - 1];
    }
  }
  for(int j = 0; j <= W; j++) {
    for(int i = 1; i <= H; i++) {
      c[i][j] += c[i - 1][j];
    }
  }
}

int main() {
  cin >> H >> W >> N;
  K = max(H, W);
  for(int i = 0; i <= K; i++) {
    for(int j = 0; j <= K; j++) {
      a[i][j] = 0;
    }
  }
  for(int i = 0; i < H; i++) {
    for(int j = 0; j < W; j++) {
      cin >> a[i][j];
    }
  }
  long long ans = 0;
  if(N == 2) {
    rotate();
    for(int i = 0; i < H - 1; i++) {
      ans = max(ans, min(f(0, i, 0, W - 1), f(i + 1, H - 1, 0, W - 1)));
    }
    for(int j = 0; j < W - 1; j++) {
      ans = max(ans, min(f(0, H - 1, 0, j), f(0, H - 1, j + 1, W - 1)));
    }
    cout << ans << endl;
    return 0;
  }
  for(int _t = 0; _t < 4; _t++) {
    rotate();
    // 横2本
    for(int i = 0; i < H; i++) {
      for(int j = i + 1; j + 1 < H; j++) {
        const int k = H - 1;
        if(N == 3) {
          const long long cur = min(f(0, i, 0, W - 1), min(f(i + 1, j, 0, W - 1), f(j + 1, k, 0, W - 1)));
          ans = max(ans, cur);
          continue;
        }
        {
          const long long val_org = min(f(i + 1, j, 0, W - 1), f(j + 1, k, 0, W - 1));
          ans = max(ans, min(val_org, div_opt(0, i, 0, W - 1)));
        }
        {
          const long long val_org = min(f(0, i, 0, W - 1), f(j + 1, k, 0, W - 1));
          ans = max(ans, min(val_org, div_opt(i + 1, j, 0, W - 1)));
        }
        {
          const long long val_org = min(f(i + 1, j, 0, W - 1), f(0, i, 0, W - 1));
          ans = max(ans, min(val_org, div_opt(j + 1, k, 0, W - 1)));
        }
      }
    }
    // 縦横
    for(int i = 0; i < H; i++) {
      for(int j = 0; j < W - 1; j++) {
        const int k = H - 1;
        if(N == 3) {
          const long long cur = min(f(0, i, 0, W - 1), min(f(i + 1, k, 0, j), f(i + 1, k, j + 1, W - 1)));
          ans = max(ans, cur);
          continue;
        }
        {
          const long long val_org =  min(f(i + 1, k, 0, j), f(i + 1, k, j + 1, W - 1));
          ans = max(ans, min(val_org, div_opt(0, i, 0, W - 1)));
        }
        {
          const long long val_org = min(f(0, i, 0, W - 1), f(i + 1, k, j + 1, W - 1));
          ans = max(ans, min(val_org, div_opt(i + 1, k, 0, j)));
        }
        {
          const long long val_org = min(f(i + 1, k, 0, j), f(0, i, 0, W - 1));
          ans = max(ans, min(val_org, div_opt(i + 1, k, j + 1, W - 1)));
        }
      }
    }
  }
  cout << ans << endl;
}
accuracy: 0.8181818181818182
time_ms: 60
memory_kb: 4096
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;

int H, W, N, K;
long long a[205][205];
long long c[205][205];

long long f(int u, int d, int l, int r) {
  return c[d + 1][r + 1] + c[u][l] - c[d + 1][l] - c[u][r + 1];
}

int bin_ho(int u, int d, int l, int r) {
  assert(u < d);
  if(u + 1 == d) return u;
  int ok = u, ng = d;
  while(ok + 1 < ng) {
    int k = (ok + ng) / 2;
    if(f(u, k, l, r) < f(k + 1, d, l, r)) ok = k;
    else ng = k;
  }
  if(ng == d) return ok;
  const long long val_ok = min(f(u, ok, l, r), f(ok + 1, d, l, r));
  const long long val_ng = min(f(u, ng, l, r), f(ng + 1, d, l, r));
  return (val_ok > val_ng ? ok : ng);
}

int bin_ve(int u, int d, int l, int r) {
  assert(l < r);
  if(l + 1 == r) return l;
  int ok = l, ng = r;
  while(ok + 1 < ng) {
    int k = (ok + ng) / 2;
    if(f(u, d, l, k) < f(u, d, k + 1, r)) ok = k;
    else ng = k;
  }
  if(ng == r) return ok;
  const long long val_ok = min(f(u, d, l, ok), f(u, d, ok + 1, r));
  const long long val_ng = min(f(u, d, l, ng), f(u, d, ng + 1, r));
  return (val_ok > val_ng ? ok : ng);
}

long long div_opt(int u, int d, int l, int r) {
  long long ret = 0;
  if(u < d) {
    const int m = bin_ho(u, d, l, r);
    ret = max(ret, min(f(u, m, l, r), f(m + 1, d, l, r)));
  }
  if(l < r) {
    const int m = bin_ve(u, d, l, r);
    ret = max(ret, min(f(u, d, l, m), f(u, d, m + 1, r)));
  }
  return ret;
}

void rotate()
{
  for (int i = 0; i <= K; i++) {
    for (int j = 0; j <= K; j++) {
      c[i][j] = 0;
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      c[W - 1 - j][i] = a[i][j];
    }
  }
  for (int i = 0; i <= K; i++) {
    for (int j = 0; j <= K; j++) {
      a[i][j] = 0;
    }
  }
  swap(H, W);
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      a[i][j] = c[i][j];
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      c[i + 1][j + 1] = a[i][j];
    }
  }
  for(int i = 0; i <= H; i++) {
    for(int j = 1; j <= W; j++) {
      c[i][j] += c[i][j - 1];
    }
  }
  for(int j = 0; j <= W; j++) {
    for(int i = 1; i <= H; i++) {
      c[i][j] += c[i - 1][j];
    }
  }
}

int main() {
  cin >> H >> W >> N;
  K = max(H, W);
  for(int i = 0; i <= K; i++) {
    for(int j = 0; j <= K; j++) {
      a[i][j] = 0;
    }
  }
  for(int i = 0; i < H; i++) {
    for(int j = 0; j < W; j++) {
      cin >> a[i][j];
    }
  }
  long long ans = 0;
  if(N == 2) {
    rotate();
    for(int i = 0; i < H - 1; i++) {
      ans = max(ans, min(f(0, i, 0, W - 1), f(i + 1, H - 1, 0, W - 1)));
    }
    for(int j = 0; j < W - 1; j++) {
      ans = max(ans, min(f(0, H - 1, 0, j), f(0, H - 1, j + 1, W - 1)));
    }
    cout << ans << endl;
    return 0;
  }
  for(int _t = 0; _t < 4; _t++) {
    rotate();
    // 横2本
    for(int i = 0; i < H; i++) {
      for(int j = i + 1; j + 1 < H; j++) {
        const int k = H - 1;
        if(N == 3) {
          const long long cur = min(f(0, i, 0, W - 1), min(f(i + 1, j, 0, W - 1), f(j + 1, k, 0, W - 1)));
          ans = max(ans, cur);
          continue;
        }
        {
          const long long val_org = min(f(i + 1, j, 0, W - 1), f(j + 1, k, 0, W - 1));
          ans = max(ans, min(val_org, div_opt(0, i, 0, W - 1)));
        }
        {
          const long long val_org = min(f(0, i, 0, W - 1), f(j + 1, k, 0, W - 1));
          ans = max(ans, min(val_org, div_opt(i + 1, j, 0, W - 1)));
        }
        {
          const long long val_org = min(f(i + 1, j, 0, W - 1), f(0, i, 0, W - 1));
          ans = max(ans, min(val_org, div_opt(j + 1, k, 0, W - 1)));
        }
      }
    }
    // 縦横
    for(int i = 0; i < H; i++) {
      for(int j = 0; j < W - 1; j++) {
        const int k = H - 1;
        if(N == 3) {
          const long long cur = min(f(0, i, 0, W - 1), min(f(i + 1, k, 0, j), f(i + 1, k, j + 1, W - 1)));
          ans = max(ans, cur);
          continue;
        }
        {
          const long long val_org =  min(f(i + 1, k, 0, j), f(i + 1, k, j + 1, W - 1));
          ans = max(ans, min(val_org, div_opt(0, i, 0, W - 1)));
        }
        {
          const long long val_org = min(f(0, i, 0, W - 1), f(i + 1, k, j + 1, W - 1));
          ans = max(ans, min(val_org, div_opt(i + 1, k, 0, j)));
        }
        {
          const long long val_org = min(f(i + 1, j, 0, W - 1), f(0, i, 0, W - 1));
          ans = max(ans, min(val_org, div_opt(i + 1, k, j + 1, W - 1)));
        }
      }
    }
  }
  cout << ans << endl;
}
accuracy: 0.32727272727272727
time_ms: 50
memory_kb: 4088
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;

int H, W, N, K;
long long a[205][205];
long long c[205][205];

long long f(int u, int d, int l, int r) {
  return c[d + 1][r + 1] + c[u][l] - c[d + 1][l] - c[u][r + 1];
}

int bin_ho(int u, int d, int l, int r) {
  assert(u < d);
  if(u + 1 == d) return u;
  int ok = u, ng = d;
  while(ok + 1 < ng) {
    int k = (ok + ng) / 2;
    if(f(u, k, l, r) < f(k + 1, d, l, r)) ok = k;
    else ng = k;
  }
  if(ng == d) return ok;
  const long long val_ok = min(f(u, ok, l, r), f(ok + 1, d, l, r));
  const long long val_ng = min(f(u, ng, l, r), f(ng + 1, d, l, r));
  return (val_ok > val_ng ? ok : ng);
}

int bin_ve(int u, int d, int l, int r) {
  assert(l < r);
  if(l + 1 == r) return l;
  int ok = l, ng = r;
  while(ok + 1 < ng) {
    int k = (ok + ng) / 2;
    if(f(u, d, l, k) < f(u, d, k + 1, r)) ok = k;
    else ng = k;
  }
  if(ng == r) return ok;
  const long long val_ok = min(f(u, d, l, ok), f(u, d, ok + 1, r));
  const long long val_ng = min(f(u, d, l, ng), f(u, d, ng + 1, r));
  return (val_ok > val_ng ? ok : ng);
}

long long div_opt(int u, int d, int l, int r) {
  long long ret = 0;
  if(u < d) {
    const int m = bin_ho(u, d, l, r);
    ret = max(ret, min(f(u, m, l, r), f(m + 1, d, l, r)));
  }
  if(l < r) {
    const int m = bin_ve(u, d, l, r);
    ret = max(ret, min(f(u, d, l, m), f(u, d, m + 1, r)));
  }
  return ret;
}

void rotate()
{
  for (int i = 0; i <= K; i++) {
    for (int j = 0; j <= K; j++) {
      c[i][j] = 0;
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      c[W - 1 - j][i] = a[i][j];
    }
  }
  for (int i = 0; i <= K; i++) {
    for (int j = 0; j <= K; j++) {
      a[i][j] = 0;
    }
  }
  swap(H, W);
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      a[i][j] = c[i][j];
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      c[i + 1][j + 1] = a[i][j];
    }
  }
  for(int i = 0; i <= H; i++) {
    for(int j = 1; j <= W; j++) {
      c[i][j] += c[i][j - 1];
    }
  }
  for(int j = 0; j <= W; j++) {
    for(int i = 1; i <= H; i++) {
      c[i][j] += c[i - 1][j];
    }
  }
}

int main() {
  cin >> H >> W >> N;
  K = max(H, W);
  for(int i = 0; i <= K; i++) {
    for(int j = 0; j <= K; j++) {
      a[i][j] = 0;
    }
  }
  for(int i = 0; i < H; i++) {
    for(int j = 0; j < W; j++) {
      cin >> a[i][j];
    }
  }
  long long ans = 0;
  if(N == 2) {
    rotate();
    for(int i = 0; i < H - 1; i++) {
      ans = max(ans, min(f(0, i, 0, W - 1), f(i + 1, H - 1, 0, W - 1)));
    }
    for(int j = 0; j < W - 1; j++) {
      ans = max(ans, min(f(0, H - 1, 0, j), f(0, H - 1, j + 1, W - 1)));
    }
    cout << ans << endl;
    return 0;
  }
  for(int _t = 0; _t < 4; _t++) {
    rotate();
    // 横2本
    for(int i = 0; i < H; i++) {
      for(int j = i + 1; j + 1 < H; j++) {
        const int k = H - 1;
        if(N == 3) {
          const long long cur = min(f(0, i, 0, W - 1), min(f(i + 1, j, 0, W - 1), f(j + 1, k, 0, W - 1)));
          ans = max(ans, cur);
          continue;
        }
        {
          const long long val_org = min(f(i + 1, j, 0, W - 1), f(j + 1, k, 0, W - 1));
          ans = max(ans, min(val_org, div_opt(0, i, 0, W - 1)));
        }
        {
          const long long val_org = min(f(0, i, 0, W - 1), f(j + 1, k, 0, W - 1));
          ans = max(ans, min(val_org, div_opt(i + 1, j, 0, W - 1)));
        }
        {
          const long long val_org = min(f(i + 1, j, 0, W - 1), f(0, i, 0, W - 1));
          ans = max(ans, min(val_org, div_opt(j + 1, k, 0, W - 1)));
        }
      }
    }
    // 縦横
    for(int i = 0; i < H; i++) {
      for(int j = 0; j < W - 1; j++) {
        const int k = H - 1;
        if(N == 3) {
          const long long cur = min(f(0, i, 0, W - 1), min(f(i + 1, k, 0, j), f(i + 1, k, j + 1, W - 1)));
          ans = max(ans, cur);
          continue;
        }
        {
          const long long val_org =  min(f(i + 1, k, 0, j), f(i + 1, k, j + 1, W - 1));
          ans = max(ans, min(val_org, div_opt(0, i, 0, W - 1)));
        }
        {
          const long long val_org = min(f(0, i, 0, W - 1), f(i + 1, k, j + 1, W - 1));
          ans = max(ans, min(val_org, div_opt(i + 1, k, 0, j)));
        }
        {
          const long long val_org = min(f(i + 1, j, 0, W - 1), f(0, i, 0, W - 1));
          ans = max(ans, min(val_org, div_opt(i + 1, k, j + 1, W - 1)));
        }
      }
    }
  }
  cout << ans << endl;
}

// int main() {
//   int H, W, N;
//   cin >> H >> W >> N;
//   for(int i = 0; i <= max(H, W); i++) {
//     for(int j = 0; j <= max(H, W); j++) {
//       a[i][j] = 0;
//     }
//   }
//   for(int i = 1; i <= H; i++) {
//     for(int j = 1; j <= W; j++) {
//       cin >> a[i][j];
//     }
//   }
//   for(int i = 0; i <= H; i++) {
//     for(int j = 1; j <= W; j++) {
//       a[i][j] += a[i][j - 1];
//     }
//   }
//   for(int j = 0; j <= W; j++) {
//     for(int i = 1; i <= H; i++) {
//       a[i][j] += a[i - 1][j];
//     }
//   }
//   auto bin = [&](int u, int d, int l, long long x) -> int {
//     if(f(u, d, l, l) >= x) return l;
//     if(f(u, d, l, W - 1) < x) return -1;
//     int ng = l, ok = W - 1;
//     while(ng + 1 < ok) {
//       int mid = (ng + ok) / 2;
//       if(f(u, d, l, mid) < x) ng = mid;
//       else ok = mid;
//     }
//     return ok;
//   };
//   auto dfs = [&](auto dfs, int pre, int rem, int cnt_ok, long long x) -> bool {
//     bool ret = false;
//     for(int cur = pre + 1; cur < H; cur++) {
//       int l = 0;
//       int cnt_plus = 0;
//       while(cnt_plus + cnt_ok < N) {
//         l = bin(pre + 1, cur, l, x);
//         if(l == -1) break;
//         cnt_plus++;
//         l++;
//       }
//       if(cnt_ok + cnt_plus == N) { ret = true; break; }
//       if(dfs(dfs, cur, rem - cnt_plus, cnt_ok + cnt_plus, x)) { ret = true; break; }
//     }
//     return ret;
//   };
//   long long ans = 0;
//   for(int _t = 0; _t < 4; _t++) {
    
//     long long ok = 0LL, ng = 1LL << 30;
//     while(ok + 1 < ng) {
//       long long x = (ok + ng) / 2;
//       if(dfs(dfs, -1, N - 1, 0, x)) ok = x;
//       else ng = x;
//     }
//     ans = max(ans, ok);
//   }
//   cout << ans << endl;
// }
accuracy: 0.32727272727272727
time_ms: 60
memory_kb: 4068
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define ll long long
#define elif else if
#define vi vector<int>
#define vll vector<ll>
#define vvi vector<vi>
#define pii pair<int,int>


#define repname(a, b, c, d, e, ...) e
#define rep(...)                    repname(__VA_ARGS__, rep3, rep2, rep1, rep0)(__VA_ARGS__)
#define rep0(x)                     for (int rep_counter = 0; rep_counter < (x); ++rep_counter)
#define rep1(i, x)                  for (int i = 0; i < (x); ++i)
#define rep2(i, l, r)               for (int i = (l); i < (r); ++i)
#define rep3(i, l, r, c)            for (int i = (l); i < (r); i += (c))





struct ScalarInput {
    template<class T>
    operator T(){
        T ret;
        cin >> ret;
        return ret;
    }
};
struct VectorInput {
    size_t n;
    VectorInput(size_t n): n(n) {}
    template<class T>
    operator vector<T>(){
        vector<T> ret(n);
        for(T &x : ret) cin >> x;
        return ret;
    }
};
ScalarInput input(){ return ScalarInput(); }
VectorInput input(size_t n){ return VectorInput(n); }

template<typename T>
void print(vector<T> a){
  for(int i=0;i<a.size();i++){
    cout<<a[i]<<" \n"[i+1==a.size()];
  }
}

template<class T>
void print(T x){
    cout << x << '\n';
}
 
template <class Head, class... Tail>
void print(Head&& head, Tail&&... tail){
  cout << head << ' ';
  print(forward<Tail>(tail)...);
}

template< class T >
struct CumulativeSum2D {
  vector< vector< T > > data;

  CumulativeSum2D(int W, int H) : data(W + 1, vector< int >(H + 1, 0)) {}

  void add(int x, int y, T z) {
    ++x, ++y;
    if(x >= data.size() || y >= data[0].size()) return;
    data[x][y] += z;
  }

  void build() {
    for(int i = 1; i < data.size(); i++) {
      for(int j = 1; j < data[i].size(); j++) {
        data[i][j] += data[i][j - 1] + data[i - 1][j] - data[i - 1][j - 1];
      }
    }
  }

  T query(int sx, int sy, int gx, int gy) {
    return (data[gx][gy] - data[sx][gy] - data[gx][sy] + data[sx][sy]);
  }
};

int H,W;

ll ID(ll xL,ll xR,ll yL,ll yR,ll k){
  return (((xL*200+xR)*200+yL)*200+yR)*5+k;

}
int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int H,W,N;
  cin>>H>>W>>N;
  vector<vector<int>>A(H,vector<int>(W));
  rep(x,H)rep(y,W){
    cin>>A[x][y];
  }

  CumulativeSum2D<int>C(H,W);
  rep(x,H)rep(y,W){
    C.add(x,y,A[x][y]);
  }
  C.build();

  map<ll,int>memo;

  auto calc=[&](auto calc,int xL,int xR,int yL,int yR,int k){
    if(k==1){
      return C.query(xL,yL,xR,yR);
    }
    ll id=ID(xL,xR,yL,yR,k);
    if(memo.count(id)){
      return memo[id];
    }

    int ans=-(1<<30);

    rep(x_mid,xL+1,xR){
      rep(i,1,k){
        int j=k-i;
        int res=calc(calc,xL,x_mid,yL,yR,i);
        int res2=calc(calc,x_mid,xR,yL,yR,j);
        ans=max(ans,min(res,res2));
      }
    }
    rep(y_mid,yL+1,yR){
      rep(i,1,k){
        int j=k-i;
        int res=calc(calc,xL,xR,yL,y_mid,i);
        int res2=calc(calc,xL,xR,y_mid,yR,j);
        ans=max(ans,min(res,res2));
      }
    }
    memo[id]=ans;
    return ans;
  };

  int ans=calc(calc,0,H,0,W,N);

  if(N==4){
    CumulativeSum2D<int>C2(H,W);
    rep(x,H)rep(y,W){
      C2.add(x,W-1-y,A[x][y]);
    }
    C2.build();

    int res1,res2,res3,res4,res;
    rep(x1,1,H){
      //cerr<<x1<<endl;
      rep(x2,x1+1,H){
        rep(y1,1,W){
          rep(y2,y1+1,W){
            res1=C.query(0,0,x1,y2);
            res2=C.query(x1,0,H,y1);
            res3=C.query(x2,y1,H,W);
            res4=C.query(0,y2,x2,W);
            //print(res1,res2,res3,res4);
            
            res=min(res1,res2);
            res=min(res,res3);
            res=min(res,res4);
            ans=max(ans,res);

            res1=C2.query(0,0,x1,y2);
            res2=C2.query(x1,0,H,y1);
            res3=C2.query(x2,y1,H,W);
            res4=C2.query(0,y2,x2,W);
            //print(res1,res2,res3,res4);
            
            
            res=min(res1,res2);
            res=min(res,res3);
            res=min(res,res4);
            ans=max(ans,res);
          }
        }
      }
    }
  }
  print(ans);
}
accuracy: 1
time_ms: 1330
memory_kb: 16400
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define ll long long
#define elif else if
#define vi vector<int>
#define vll vector<ll>
#define vvi vector<vi>
#define pii pair<int,int>


#define repname(a, b, c, d, e, ...) e
#define rep(...)                    repname(__VA_ARGS__, rep3, rep2, rep1, rep0)(__VA_ARGS__)
#define rep0(x)                     for (int rep_counter = 0; rep_counter < (x); ++rep_counter)
#define rep1(i, x)                  for (int i = 0; i < (x); ++i)
#define rep2(i, l, r)               for (int i = (l); i < (r); ++i)
#define rep3(i, l, r, c)            for (int i = (l); i < (r); i += (c))





struct ScalarInput {
    template<class T>
    operator T(){
        T ret;
        cin >> ret;
        return ret;
    }
};
struct VectorInput {
    size_t n;
    VectorInput(size_t n): n(n) {}
    template<class T>
    operator vector<T>(){
        vector<T> ret(n);
        for(T &x : ret) cin >> x;
        return ret;
    }
};
ScalarInput input(){ return ScalarInput(); }
VectorInput input(size_t n){ return VectorInput(n); }

template<typename T>
void print(vector<T> a){
  for(int i=0;i<a.size();i++){
    cout<<a[i]<<" \n"[i+1==a.size()];
  }
}

template<class T>
void print(T x){
    cout << x << '\n';
}
 
template <class Head, class... Tail>
void print(Head&& head, Tail&&... tail){
  cout << head << ' ';
  print(forward<Tail>(tail)...);
}

template< class T >
struct CumulativeSum2D {
  vector< vector< T > > data;

  CumulativeSum2D(int W, int H) : data(W + 1, vector< int >(H + 1, 0)) {}

  void add(int x, int y, T z) {
    ++x, ++y;
    if(x >= data.size() || y >= data[0].size()) return;
    data[x][y] += z;
  }

  void build() {
    for(int i = 1; i < data.size(); i++) {
      for(int j = 1; j < data[i].size(); j++) {
        data[i][j] += data[i][j - 1] + data[i - 1][j] - data[i - 1][j - 1];
      }
    }
  }

  T query(int sx, int sy, int gx, int gy) {
    return (data[gx][gy] - data[sx][gy] - data[gx][sy] + data[sx][sy]);
  }
};

int H,W;

ll ID(ll xL,ll xR,ll yL,ll yR,ll k){
  return (((xL*200+xR)*200+yL)*200+yR)*5+k;

}
int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  int H,W,N;
  cin>>H>>W>>N;
  vector<vector<int>>A(H,vector<int>(W));
  rep(x,H)rep(y,W){
    cin>>A[x][y];
  }

  CumulativeSum2D<int>C(H,W);
  rep(x,H)rep(y,W){
    C.add(x,y,A[x][y]);
  }
  C.build();

  map<ll,int>memo;

  auto calc=[&](auto calc,int xL,int xR,int yL,int yR,int k){
    if(k==1){
      return C.query(xL,yL,xR,yR);
    }
    ll id=ID(xL,xR,yL,yR,k);
    if(memo.count(id)){
      return memo[id];
    }

    int ans=-(1<<30);

    rep(x_mid,xL+1,xR){
      rep(i,1,k){
        int j=k-i;
        int res=calc(calc,xL,x_mid,yL,yR,i);
        int res2=calc(calc,x_mid,xR,yL,yR,j);
        ans=max(ans,min(res,res2));
      }
    }
    rep(y_mid,yL+1,yR){
      rep(i,1,k){
        int j=k-i;
        int res=calc(calc,xL,xR,yL,y_mid,i);
        int res2=calc(calc,xL,xR,y_mid,yR,j);
        ans=max(ans,min(res,res2));
      }
    }
    memo[id]=ans;
    return ans;
  };

  int ans=calc(calc,0,H,0,W,N);

  if(N==4){
    CumulativeSum2D<int>C2(H,W);
    rep(x,H)rep(y,W){
      C2.add(H-1-x,y,A[x][y]);
    }
    C2.build();

    int res1,res2,res3,res4,res;
    rep(x1,1,H){
      //cerr<<x1<<endl;
      rep(x2,x1+1,H){
        rep(y1,1,W){
          rep(y2,y1+1,W){
            res1=C.query(0,0,x1,y2);
            res2=C.query(x1,0,H,y1);
            res3=C.query(x2,y1,H,W);
            res4=C.query(0,y2,x2,H);
            //print(res1,res2,res3,res4);
            
            res=min(res1,res2);
            res=min(res,res3);
            res=min(res,res4);
            ans=max(ans,res);

            res1=C2.query(0,0,x1,y2);
            res2=C2.query(x1,0,H,y1);
            res3=C2.query(x2,y1,H,W);
            res4=C2.query(0,y2,x2,H);
            //print(res1,res2,res3,res4);
            
            
            res=min(res1,res2);
            res=min(res,res3);
            res=min(res,res4);
            ans=max(ans,res);
          }
        }
      }
    }
  }
  print(ans);
}
accuracy: 0.8181818181818182
time_ms: 1310
memory_kb: 16280
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
#define rep(i,n) for(ll i=0;i<ll(n);i++)
#define all(A) A.begin(),A.end()

void chmax(ll& p, ll q) { p = max(p, q); };
void chmin(ll& p, ll q) { p = min(p, q); };

const ll mod = 998244353;


vvll SA;

ll area(ll Y, ll X, ll y, ll x) {
    return SA[Y + 1][X + 1] + SA[y][x] - SA[Y + 1][x] - SA[y][X + 1];
}

//[y,x]*[Y*X]をn分割. 隙間なく. n<=3
ll maxarea(ll Y,ll X,ll y,ll x,ll n){
    if(n==1){
        //O(1)
        return area(Y,X,y,x);
    }
    if(n==2){
        //O(N)
        ll an=0;
        for(ll h=y;h<Y;h++){
            chmax(an,min(area(Y,X,h+1,x),area(h,X,y,x)));
        }
        for(ll w=x;w<X;w++){
            chmax(an,min(area(Y,X,y,w+1),area(Y,w,y,x)));
        }
        return an;
    }
    if(n==3){
        ll an=0;
        for(ll h=y;h<Y;h++){
            chmax(an,min(area(Y,X,h+1,x),maxarea(h,X,y,x,2)));
            chmax(an,min(maxarea(Y,X,h+1,x,2),area(h,X,y,x)));
        }
        for(ll w=x;w<X;w++){
            chmax(an,min(area(Y,X,y,w+1),maxarea(Y,w,y,x,2)));
            chmax(an,min(maxarea(Y,X,y,w+1,2),area(Y,w,y,x)));
        }
        return an;
    }
    if(n==4){
        ll an=0;
        for(ll h=y;h<Y;h++){
            chmax(an,min(area(Y,X,h+1,x),maxarea(h,X,y,x,3)));
            chmax(an,min(maxarea(Y,X,h+1,x,2),maxarea(h,X,y,x,2)));
            chmax(an,min(maxarea(Y,X,h+1,x,3),area(h,X,y,x)));
        }
        for(ll w=x;w<X;w++){
            chmax(an,min(area(Y,X,y,w+1),maxarea(Y,w,y,x,3)));
            chmax(an,min(maxarea(Y,X,y,w+1,2),maxarea(Y,w,y,x,2)));
            chmax(an,min(maxarea(Y,X,y,w+1,3),area(Y,w,y,x)));
        }
        return an;
    }
    return 0;
}

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    ll H, W, N;
    cin >> H >> W >> N;
    vvll A(H, vll(W));
    SA.assign(H + 1, vll(W + 1, 0));
    rep(h, H)rep(w, W) {
        cin >> A[h][w];
        SA[h + 1][w + 1] = A[h][w];
    }
    rep(h, H + 1)rep(w, W)SA[h][w + 1] += SA[h][w];
    rep(h, H)rep(w, W + 1)SA[h + 1][w] += SA[h][w];
    ll an = 0;
    if (N == 4) {
        rep(h1, H - 1)rep(h2, h1+1) {
            rep(w1, W - 1)rep(w2, w1+1) {
                if (min(h2, w2) == 0)continue;
                //[h2,h1]*[w2,w1]を取らない
                ll res = min(
                    { area(h1,w2 - 1,0,0),area(H - 1,w1,h1 + 1,0),area(H - 1,W - 1,h2,w1 + 1),area(h2 - 1,W - 1,0,w2) }
                );
                chmax(res, min(
                    { area(h2 - 1,w1,0,0),area(H - 1,w2 - 1,h2,0),area(H - 1,W - 1,h1 + 1,w2),area(h1,W - 1,0,w1 + 1) }
                )
                );
                chmax(an, res);
            }
        }
        chmax(an,maxarea(H-1,W-1,0,0,4));
    }
    if(N==2){
        cout<<maxarea(H-1,W-1,0,0,2)<<endl;
        return 0;
    }
    if(N==3){
        cout<<maxarea(H-1,W-1,0,0,3)<<endl;
        return 0;
    }






    cout << an << endl;
}
accuracy: 1
time_ms: 5080
memory_kb: 3880
final_rank: 6

code_snippet: #include <bits/stdc++.h>

int main() {
    int H, W, N;
    std::cin >> H >> W >> N;
    std::vector A(H, std::vector<int>(W));
    for (auto& a : A) for (auto& x : a) std::cin >> x;
    std::vector S(H + 1, std::vector<int>(W + 1));
    for (int i{1} ; i <= H ; i++) {
        for (int j{1} ; j <= W ; j++) {
            S[i][j] = S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1] + A[i - 1][j - 1];
        }
    }
    auto f{[&](int up, int dn, int l, int r) -> int {
        int res{};
        for (auto v : { up, dn, l, r }) {
            res = res * 200 + v;
        }
        return res;
    }};
    auto calc1{[&](int up, int dn, int l, int r) -> int {
        assert(0 <= up and up < dn and dn <= H);
        assert(0 <= l and l < r and r <= W);
        return S[dn][r] - S[dn][l] - S[up][r] + S[up][l];
    }};
    std::unordered_map<int, int> dp2;
    auto calc2{[&](int up, int dn, int l, int r) -> int {
        assert(0 <= up and up < dn and dn <= H);
        assert(0 <= l and l < r and r <= W);
        int index{f(up, dn, l, r)};
        if (dp2.find(index) != dp2.end()) return dp2[index];
        if ((dn - up) * (r - l) < 2) return dp2[index] = -1;
        int res{-1}; 
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc1(up, m, l, r), calc1(m, dn, l, r)));
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc1(up, dn, l, m), calc1(up, dn, m, r)));
        }
        return dp2[index] = res;
    }};
    std::unordered_map<int, int> dp3;
    auto calc3{[&](int up, int dn, int l, int r) -> int {
        assert(0 <= up and up < dn and dn <= H);
        assert(0 <= l and l < r and r <= W);
        int index{f(up, dn, l, r)};
        if (dp3.find(index) != dp3.end()) return dp3[index];
        if ((dn - up) * (r - l) < 3) return dp3[index] = -1;
        int res{-1};
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc2(up, m, l, r), calc1(m, dn, l, r)));
            res = std::max(res, std::min(calc1(up, m, l, r), calc2(m, dn, l, r)));
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc2(up, dn, l, m), calc1(up, dn, m, r)));
            res = std::max(res, std::min(calc1(up, dn, l, m), calc2(up, dn, m, r)));
        }
        return dp3[index] = res;
    }};
    auto calc4{[&](int up, int dn, int l, int r) -> int {
        assert(0 <= up and up < dn and dn <= H);
        assert(0 <= l and l < r and r <= W);
        assert((dn - up) * (r - l) >= 4);
        int res{-1};
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc3(up, m, l, r), calc1(m, dn, l, r)));
            res = std::max(res, std::min(calc1(up, m, l, r), calc3(m, dn, l, r)));
            res = std::max(res, std::min(calc2(up, m, l, r), calc2(m, dn, l, r)));
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc3(up, dn, l, m), calc1(up, dn, m, r)));
            res = std::max(res, std::min(calc1(up, dn, l, m), calc3(up, dn, m, r)));
            res = std::max(res, std::min(calc2(up, dn, l, m), calc2(up, dn, m, r)));
        }
        return res;
    }};
    
    if (N == 2) {
        std::cout << calc2(0, H, 0, W) << '\n';
    }
    else if (N == 3) {
        std::cout << calc3(0, H, 0, W) << '\n';
    }
    else if (N == 4) {
        int res{calc4(0, H, 0, W)};
        for (int i{1} ; i < H ; i++) {
            for (int j{1} ; j < W ; j++) {
                if (calc1(0, i, 0, j) <= res) continue;
                for (int k{1} ; k < W ; k++) {
                    if (calc1(i, H, 0, k) <= res) continue;
                    if (j < k) {
                        for (int l{1} ; l < i ; l++) {
                            res = std::max(res, 
                                    std::min({ calc1(0, i, 0, j), calc1(i, H, 0, k), calc1(l, H, k, W), calc1(0, l, j, W) }));
                        }
                    }
                    if (j > k) {
                        for (int l{i + 1} ; l < H ; l++) {
                            res = std::max(res, 
                                    std::min({ calc1(0, i, 0, j), calc1(i, H, 0, k), calc1(l, H, k, W), calc1(0, l, j, W) }));
                        }
                    }
                }
            }
        }
        std::cout << res << '\n';
    }
    else {
        assert(false);
    }
}
accuracy: 1
time_ms: 820
memory_kb: 11296
final_rank: 5

code_snippet: #include <bits/stdc++.h>

int main() {
    int H, W, N;
    std::cin >> H >> W >> N;
    std::vector A(H, std::vector<int>(W));
    for (auto& a : A) for (auto& x : a) std::cin >> x;
    std::vector S(H + 1, std::vector<int>(W + 1));
    for (int i{1} ; i <= H ; i++) {
        for (int j{1} ; j <= W ; j++) {
            S[i][j] = S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1] + A[i - 1][j - 1];
        }
    }
    auto f{[&](int up, int dn, int l, int r) -> int {
        int res{};
        for (auto v : { up, dn, l, r }) {
            res = res * 200 + v;
        }
        return res;
    }};
    auto calc1{[&](int up, int dn, int l, int r) -> int {
        assert(0 <= up and up < dn and dn <= H);
        assert(0 <= l and l < r and r <= W);
        return S[dn][r] - S[dn][l] - S[up][r] + S[up][l];
    }};
    std::unordered_map<int, int> dp2;
    auto calc2{[&](int up, int dn, int l, int r) -> int {
        assert(0 <= up and up < dn and dn <= H);
        assert(0 <= l and l < r and r <= W);
        int index{f(up, dn, l, r)};
        if (dp2.find(index) != dp2.end()) return dp2[index];
        if ((dn - up) * (r - l) < 2) return dp2[index] = -1;
        int res{-1}; 
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc1(up, m, l, r), calc1(m, dn, l, r)));
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc1(up, dn, l, m), calc1(up, dn, m, r)));
        }
        return dp2[index] = res;
    }};
    std::unordered_map<int, int> dp3;
    auto calc3{[&](int up, int dn, int l, int r) -> int {
        assert(0 <= up and up < dn and dn <= H);
        assert(0 <= l and l < r and r <= W);
        int index{f(up, dn, l, r)};
        if (dp3.find(index) != dp3.end()) return dp3[index];
        if ((dn - up) * (r - l) < 3) return dp3[index] = -1;
        int res{-1};
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc2(up, m, l, r), calc1(m, dn, l, r)));
            res = std::max(res, std::min(calc1(up, m, l, r), calc2(m, dn, l, r)));
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc2(up, dn, l, m), calc1(up, dn, m, r)));
            res = std::max(res, std::min(calc1(up, dn, l, m), calc2(up, dn, m, r)));
        }
        return dp3[index] = res;
    }};
    auto calc4{[&](int up, int dn, int l, int r) -> int {
        assert(0 <= up and up < dn and dn <= H);
        assert(0 <= l and l < r and r <= W);
        assert((dn - up) * (r - l) >= 4);
        int res{-1};
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc3(up, m, l, r), calc1(m, dn, l, r)));
            res = std::max(res, std::min(calc1(up, m, l, r), calc3(m, dn, l, r)));
            res = std::max(res, std::min(calc2(up, m, l, r), calc2(m, dn, l, r)));
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc3(up, dn, l, m), calc1(up, dn, m, r)));
            res = std::max(res, std::min(calc1(up, dn, l, m), calc3(up, dn, m, r)));
            res = std::max(res, std::min(calc2(up, dn, l, m), calc2(up, dn, m, r)));
        }
        return res;
    }};
    
    if (N == 2) {
        std::cout << calc2(0, H, 0, W) << '\n';
    }
    else if (N == 3) {
        std::cout << calc3(0, H, 0, W) << '\n';
    }
    else if (N == 4) {
        int res{calc4(0, H, 0, W)};
        for (int i{1} ; i < H ; i++) {
            for (int j{1} ; j < W ; j++) {
                if (calc1(0, i, 0, j) <= res) continue;
                for (int k{1} ; k < H ; k++) {
                    if (calc1(0, k, j, W) <= res) continue;
                    for (int l{1} ; l < W ; l++) {
                        res = std::max(res, 
                                std::min({ calc1(0, i, 0, j), calc1(i, H, 0, l), calc1(k, H, l, W), calc1(0, k, std::max(j, l), W) }));
                        // if (res > 7620) {
                        //     std::cout << res << std::endl;
                        //     std::cout << 0 << ' ' << i <<  ' ' << 0 << ' ' << j << ' ' << calc1(0, i, 0, j) << ' ' << std::endl;
                        //     std::cout << i << ' ' << H << ' ' << 0 << ' ' << l << ' ' << calc1(i, H, 0, l) << ' ' << std::endl;
                        //     std::cout << k << ' ' << H << ' ' << l << ' ' << W << ' ' << calc1(k, H, l, W) << std::endl;
                        //     std::cout << 0 << ' ' << k << ' ' << j << ' ' << W << ' ' << calc1(0, k, j, W) << std::endl;
                        //     exit(0);
                        // }
                    }
                }
            }
        }
        std::cout << res << '\n';
    }
    else {
        assert(false);
    }
}
accuracy: 0.4909090909090909
time_ms: 590
memory_kb: 11240
final_rank: 16

code_snippet: #include <bits/stdc++.h>

int main() {
    int H, W, N;
    std::cin >> H >> W >> N;
    std::vector A(H, std::vector<int>(W));
    for (auto& a : A) for (auto& x : a) std::cin >> x;
    std::vector S(H + 1, std::vector<int>(W + 1));
    for (int i{1} ; i <= H ; i++) {
        for (int j{1} ; j <= W ; j++) {
            S[i][j] = S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1] + A[i - 1][j - 1];
        }
    }
    auto f{[&](int up, int dn, int l, int r) -> int {
        int res{};
        for (auto v : { up, dn, l, r }) {
            res = res * 200 + v;
        }
        return res;
    }};
    auto calc1{[&](int up, int dn, int l, int r) -> int {
        assert(0 <= up and up < dn and dn <= H);
        assert(0 <= l and l < r and r <= W);
        return S[dn][r] - S[dn][l] - S[up][r] + S[up][l];
    }};
    std::unordered_map<int, int> dp2;
    auto calc2{[&](int up, int dn, int l, int r) -> int {
        assert(0 <= up and up < dn and dn <= H);
        assert(0 <= l and l < r and r <= W);
        int index{f(up, dn, l, r)};
        if (dp2.find(index) != dp2.end()) return dp2[index];
        if ((dn - up) * (r - l) < 2) return dp2[index] = -1;
        int res{-1}; 
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc1(up, m, l, r), calc1(m, dn, l, r)));
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc1(up, dn, l, m), calc1(up, dn, m, r)));
        }
        return dp2[index] = res;
    }};
    std::unordered_map<int, int> dp3;
    auto calc3{[&](int up, int dn, int l, int r) -> int {
        assert(0 <= up and up < dn and dn <= H);
        assert(0 <= l and l < r and r <= W);
        int index{f(up, dn, l, r)};
        if (dp3.find(index) != dp3.end()) return dp3[index];
        if ((dn - up) * (r - l) < 3) return dp3[index] = -1;
        int res{-1};
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc2(up, m, l, r), calc1(m, dn, l, r)));
            res = std::max(res, std::min(calc1(up, m, l, r), calc2(m, dn, l, r)));
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc2(up, dn, l, m), calc1(up, dn, m, r)));
            res = std::max(res, std::min(calc1(up, dn, l, m), calc2(up, dn, m, r)));
        }
        return dp3[index] = res;
    }};
    auto calc4{[&](int up, int dn, int l, int r) -> int {
        assert(0 <= up and up < dn and dn <= H);
        assert(0 <= l and l < r and r <= W);
        assert((dn - up) * (r - l) >= 4);
        int res{-1};
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc3(up, m, l, r), calc1(m, dn, l, r)));
            res = std::max(res, std::min(calc1(up, m, l, r), calc3(m, dn, l, r)));
            res = std::max(res, std::min(calc2(up, m, l, r), calc2(m, dn, l, r)));
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc3(up, dn, l, m), calc1(up, dn, m, r)));
            res = std::max(res, std::min(calc1(up, dn, l, m), calc3(up, dn, m, r)));
            res = std::max(res, std::min(calc2(up, dn, l, m), calc2(up, dn, m, r)));
        }
        return res;
    }};
    
    if (N == 2) {
        std::cout << calc2(0, H, 0, W) << '\n';
    }
    else if (N == 3) {
        std::cout << calc3(0, H, 0, W) << '\n';
    }
    else if (N == 4) {
        int res{calc4(0, H, 0, W)};
        for (int i{1} ; i < H ; i++) {
            for (int j{1} ; j < W ; j++) {
                if (calc1(0, i, 0, j) <= res) continue;
                for (int k{1} ; k < H ; k++) {
                    if (calc1(0, k, j, W) <= res) continue;
                    for (int l{1} ; l < W ; l++) {
                        res = std::max(res, 
                                std::min({ calc1(0, i, 0, j), calc1(i, H, 0, l), calc1(k, H, l, W), calc1(0, k, j, W) }));
                    }
                }
            }
        }
        std::cout << res << '\n';
    }
    else {
        assert(false);
    }
}
accuracy: 0.36363636363636365
time_ms: 480
memory_kb: 11184
final_rank: 17

code_snippet: #include <bits/stdc++.h>

int main() {
    int H, W, N;
    std::cin >> H >> W >> N;
    std::vector A(H, std::vector<int>(W));
    for (auto& a : A) for (auto& x : a) std::cin >> x;
    std::vector S(H + 1, std::vector<int>(W + 1));
    for (int i{1} ; i <= H ; i++) {
        for (int j{1} ; j <= W ; j++) {
            S[i][j] = S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1] + A[i - 1][j - 1];
        }
    }
    auto f{[&](int up, int dn, int l, int r) -> int {
        int res{};
        for (auto v : { up, dn, l, r }) {
            res = res * 200 + v;
        }
        return res;
    }};
    auto calc1{[&](int up, int dn, int l, int r) -> int {
        assert(0 <= up and up < dn and dn <= H);
        assert(0 <= l and l < r and r <= W);
        return S[dn][r] - S[dn][l] - S[up][r] + S[up][l];
    }};
    std::unordered_map<int, int> dp2;
    auto calc2{[&](int up, int dn, int l, int r) -> int {
        assert(0 <= up and up < dn and dn <= H);
        assert(0 <= l and l < r and r <= W);
        int index{f(up, dn, l, r)};
        if (dp2.find(index) != dp2.end()) return dp2[index];
        if ((dn - up) * (r - l) < 2) return dp2[index] = -1;
        int res{-1}; 
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc1(up, m, l, r), calc1(m, dn, l, r)));
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc1(up, dn, l, m), calc1(up, dn, m, r)));
        }
        return dp2[index] = res;
    }};
    std::unordered_map<int, int> dp3;
    auto calc3{[&](int up, int dn, int l, int r) -> int {
        assert(0 <= up and up < dn and dn <= H);
        assert(0 <= l and l < r and r <= W);
        int index{f(up, dn, l, r)};
        if (dp3.find(index) != dp3.end()) return dp3[index];
        if ((dn - up) * (r - l) < 3) return dp3[index] = -1;
        int res{-1};
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc2(up, m, l, r), calc1(m, dn, l, r)));
            res = std::max(res, std::min(calc1(up, m, l, r), calc2(m, dn, l, r)));
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc2(up, dn, l, m), calc1(up, dn, m, r)));
            res = std::max(res, std::min(calc1(up, dn, l, m), calc2(up, dn, m, r)));
        }
        return dp3[index] = res;
    }};
    auto calc4{[&](int up, int dn, int l, int r) -> int {
        assert(0 <= up and up < dn and dn <= H);
        assert(0 <= l and l < r and r <= W);
        assert((dn - up) * (r - l) >= 4);
        int res{-1};
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc3(up, m, l, r), calc1(m, dn, l, r)));
            res = std::max(res, std::min(calc1(up, m, l, r), calc3(m, dn, l, r)));
            res = std::max(res, std::min(calc2(up, m, l, r), calc2(m, dn, l, r)));
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc3(up, dn, l, m), calc1(up, dn, m, r)));
            res = std::max(res, std::min(calc1(up, dn, l, m), calc3(up, dn, m, r)));
            res = std::max(res, std::min(calc2(up, dn, l, m), calc2(up, dn, m, r)));
        }
        return res;
    }};
    
    if (N == 2) {
        std::cout << calc2(0, H, 0, W) << '\n';
    }
    else if (N == 3) {
        std::cout << calc3(0, H, 0, W) << '\n';
    }
    else if (N == 4) {
        int res{calc4(0, H, 0, W)};
        // for (int i{1} ; i < H ; i++) {
        //     for (int j{1} ; j < W ; j++) {
        //         if (calc1(0, i, 0, j) <= res) continue;
        //         for (int k{1} ; k < H ; k++) {
        //             if (calc1(0, k, j, W) <= res) continue;
        //             for (int l{1} ; l < W ; l++) {
        //                 res = std::max(res, 
        //                         std::min({ calc1(0, i, 0, j), calc1(i, H, 0, l), calc1(k, H, l, W), calc1(0, k, j, W) }));
        //             }
        //         }
        //     }
        // }
        std::cout << res << '\n';
    }
    else {
        assert(false);
    }
}
accuracy: 0.8181818181818182
time_ms: 90
memory_kb: 11316
final_rank: 14

code_snippet: #include <bits/stdc++.h>

int main() {
    int H, W, N;
    std::cin >> H >> W >> N;
    std::vector A(H, std::vector<int>(W));
    for (int i{} ; i < H ; i++) {
        for (int j{} ; j < W ; j++) {
            std::cin >> A[i][j];
        }
    }
    std::vector S(H + 1, std::vector<int>(W + 1));
    for (int i{1} ; i <= H ; i++) {
        for (int j{1} ; j <= W ; j++) {
            S[i][j] = -S[i - 1][j - 1] + S[i - 1][j] + S[i][j - 1] + A[i - 1][j - 1];
        }
    }
    // for (int i{} ; i <= H ; i++) {
    //     for (int j{} ; j <= W ; j++) {
    //         std::cout << S[i][j] << ' ';
    //     }
    //     std::cout << std::endl;
    // }
    auto f{[&](int i, int j, int k, int l) -> int {
        int res{};
        for (auto v : { i, j, k, l }) {
            res = res * 200 + v;
        }
        return res;
    }};
    auto calc1{[&](int up, int dn, int l, int r) -> int {
        assert(up < dn and l < r);
        return S[dn][r] - S[dn][l] - S[up][r] + S[up][l];
    }};
    std::unordered_map<int, int> dp2;
    auto calc2{[&](int up, int dn, int l, int r) -> int {
        auto it{dp2.find(f(up, dn, l, r))};
        if (it != dp2.end()) return it->second;
        if ((dn - up) * (r - l) < 2) return dp2[f(up, dn, l, r)] = -1;
        int res{-1};
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc1(up, m, l, r), calc1(m, dn, l, r))); 
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc1(up, dn, l, m), calc1(up, dn, m, r)));
        }
        return dp2[f(up, dn, l, r)] = res;
    }};
    std::unordered_map<int, int> dp3;
    auto calc3{[&](int up, int dn, int l, int r) -> int {
        auto it{dp3.find(f(up, dn, l, r))};
        if (it != dp3.end()) return it->second;
        if ((dn - up) * (r - l) < 3) return dp3[f(up, dn, l, r)] = -1;
        int res{-1};
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc1(up, m, l, r), calc2(m, dn, l, r))); 
            res = std::max(res, std::min(calc2(up, m, l, r), calc1(m, dn, l, r))); 
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc1(up, dn, l, m), calc2(up, dn, m, r)));
            res = std::max(res, std::min(calc2(up, dn, l, m), calc1(up, dn, m, r)));
        }
        return dp3[f(up, dn, l, r)] = res;
    }};
    std::unordered_map<int, int> dp4;
    auto calc4{[&](int up, int dn, int l, int r) -> int {
        int res{-1};
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc1(up, m, l, r), calc3(m, dn, l, r))); 
            res = std::max(res, std::min(calc3(up, m, l, r), calc1(m, dn, l, r))); 
            res = std::max(res, std::min(calc2(up, m, l, r), calc2(m, dn, l, r))); 
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc1(up, dn, l, m), calc3(up, dn, m, r)));
            res = std::max(res, std::min(calc3(up, dn, l, m), calc1(up, dn, m, r)));
            res = std::max(res, std::min(calc2(up, dn, l, m), calc2(up, dn, m, r)));
        }
        return res;
    }};
    if (N == 2) {
        std::cout << calc2(0, H, 0, W) << '\n';
    }
    else if (N == 3) {
        std::cout << calc3(0, H, 0, W) << '\n';
    }
    else if (N == 4) {
        std::cout << calc4(0, H, 0, W) << '\n';
    }
    else {
        assert(false);
    }
}
accuracy: 0.8181818181818182
time_ms: 80
memory_kb: 11316
final_rank: 13

code_snippet: #include <bits/stdc++.h>

int main() {
    int H, W, N;
    std::cin >> H >> W >> N;
    std::vector A(H, std::vector<int>(W));
    for (int i{} ; i < H ; i++) {
        for (int j{} ; j < W ; j++) {
            std::cin >> A[i][j];
        }
    }
    std::vector S(H + 1, std::vector<int>(W + 1));
    for (int i{1} ; i <= H ; i++) {
        for (int j{1} ; j <= W ; j++) {
            S[i][j] = -S[i - 1][j - 1] + S[i - 1][j] + S[i][j - 1] + A[i - 1][j - 1];
        }
    }
    // for (int i{} ; i <= H ; i++) {
    //     for (int j{} ; j <= W ; j++) {
    //         std::cout << S[i][j] << ' ';
    //     }
    //     std::cout << std::endl;
    // }
    auto f{[&](int i, int j, int k, int l) -> int {
        int res{};
        for (auto v : { i, j, k, l }) {
            res = res * 200 + v;
        }
        return res;
    }};
    auto calc1{[&](int up, int dn, int l, int r) -> int {
        assert(up <= dn and l <= r);
        return S[dn][r] - S[dn][l] - S[up][r] + S[up][l];
    }};
    std::unordered_map<int, int> dp2;
    auto calc2{[&](int up, int dn, int l, int r) -> int {
        auto it{dp2.find(f(up, dn, l, r))};
        if (it != dp2.end()) return it->second;
        int res{-1};
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc1(up, m, l, r), calc1(m, dn, l, r))); 
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc1(up, dn, l, m), calc1(up, dn, m, r)));
        }
        return dp2[f(up, dn, l, r)] = res;
    }};
    std::unordered_map<int, int> dp3;
    auto calc3{[&](int up, int dn, int l, int r) -> int {
        auto it{dp3.find(f(up, dn, l, r))};
        if (it != dp3.end()) return it->second;
        int res{-1};
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc1(up, m, l, r), calc2(m, dn, l, r))); 
            res = std::max(res, std::min(calc2(up, m, l, r), calc1(m, dn, l, r))); 
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc1(up, dn, l, m), calc2(up, dn, m, r)));
            res = std::max(res, std::min(calc2(up, dn, l, m), calc1(up, dn, m, r)));
        }
        return dp3[f(up, dn, l, r)] = res;
    }};
    std::unordered_map<int, int> dp4;
    auto calc4{[&](int up, int dn, int l, int r) -> int {
        int res{-1};
        for (int m{up + 1} ; m < dn ; m++) {
            res = std::max(res, std::min(calc1(up, m, l, r), calc3(m, dn, l, r))); 
            res = std::max(res, std::min(calc3(up, m, l, r), calc1(m, dn, l, r))); 
            res = std::max(res, std::min(calc2(up, m, l, r), calc2(m, dn, l, r))); 
        }
        for (int m{l + 1} ; m < r ; m++) {
            res = std::max(res, std::min(calc1(up, dn, l, m), calc3(up, dn, m, r)));
            res = std::max(res, std::min(calc3(up, dn, l, m), calc1(up, dn, m, r)));
            res = std::max(res, std::min(calc2(up, dn, l, m), calc2(up, dn, m, r)));
        }
        return res;
    }};
    if (N == 2) {
        std::cout << calc2(0, H, 0, W) << '\n';
    }
    else if (N == 3) {
        std::cout << calc3(0, H, 0, W) << '\n';
    }
    else if (N == 4) {
        std::cout << calc4(0, H, 0, W) << '\n';
    }
    else {
        assert(false);
    }
}
accuracy: 0.8181818181818182
time_ms: 80
memory_kb: 11192
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, a, b) for(ll i = a; i < b; ++i)
#define rrep(i, a, b) for(ll i = a; i >= b; --i)
constexpr ll inf = 4e18;
template <typename T>
struct CumlativeSum2D {
    CumlativeSum2D(int H, int W)
        : h(H), w(W), data(H + 1, vector<T>(W + 1, 0)) {}

    void add(int i, int j, T x) {
        data[i + 1][j + 1] += x;
    }
    void init() {
        for(int i = 1; i < (int)data.size(); ++i) {
            for(int j = 1; j < (int)data[i].size(); ++j) {
                data[i][j] += data[i][j - 1] + data[i - 1][j] - data[i - 1][j - 1];
            }
        }
    }
    inline T sum(int li, int lj, int ri, int rj) {
        return data[ri][rj] - data[li][rj] - data[ri][lj] + data[li][lj];
    }
    T get(int i, int j) {
        return data[i + 1][j + 1] - data[i][j + 1] - data[i + 1][j] + data[i][j];
    }

   private:
    int h, w;
    vector<vector<T>> data;
};
int main(void) {
    cin.tie(0);
    ios::sync_with_stdio(0);
    int H, W, N;
    cin >> H >> W >> N;
    CumlativeSum2D<int> cum(H, W);
    rep(i, 0, H) {
        rep(j, 0, W) {
            int a;
            cin >> a;
            cum.add(i, j, a);
        }
    }
    cum.init();
    auto func = [&](auto& func, int lh, int lw, int rh, int rw, int n) -> int {
        int res = 0;
        if(n == 2) {
            rep(i, lh + 1, rh) {
                res = max(res, min(cum.sum(lh, lw, i, rw), cum.sum(i, lw, rh, rw)));
            }
            rep(i, lw + 1, rw) {
                res = max(res, min(cum.sum(lh, lw, rh, i), cum.sum(lh, i, rh, rw)));
            }
        } else if(n == 3) {
            rep(i, lh + 1, rh) {
                res = max(res, min(cum.sum(lh, lw, i, rw), func(func, i, lw, rh, rw, n - 1)));
                res = max(res, min(cum.sum(i, lw, rh, rw), func(func, lh, lw, i, rw, n - 1)));
            }
            rep(i, lw + 1, rw) {
                res = max(res, min(cum.sum(lh, lw, rh, i), func(func, lh, i, rh, rw, n - 1)));
                res = max(res, min(cum.sum(lh, i, rh, rw), func(func, lh, lw, rh, i, n - 1)));
            }
        } else if(n == 4) {
            rep(i, lh + 1, rh) {
                res = max(res, min(cum.sum(lh, lw, i, rw), func(func, i, lw, rh, rw, n - 1)));
                res = max(res, min(cum.sum(i, lw, rh, rw), func(func, lh, lw, i, rw, n - 1)));
            }
            rep(i, lw + 1, rw) {
                res = max(res, min(cum.sum(lh, lw, rh, i), func(func, lh, i, rh, rw, n - 1)));
                res = max(res, min(cum.sum(lh, i, rh, rw), func(func, lh, lw, rh, i, n - 1)));
            }
            rep(i, lh + 1, rh) {
                rep(j, lw + 1, rw) {
                    rep(k, lh + 1, i + 1) {
                        rep(l, lh + 1, j + 1) {
                            res = max(res, min({cum.sum(lh, lw, i, l), cum.sum(i, lw, rh, j), cum.sum(k, j, rh, rw), cum.sum(lh, l, k, rw)}));
                        }
                    }
                }
            }
            rep(i, lh + 1, rh) {
                rep(j, lw + 1, rw) {
                    rep(k, i, rh) {
                        rep(l, j, rw) {
                            res = max(res, min({cum.sum(lh, lw, i, l), cum.sum(i, lw, rh, j), cum.sum(k, j, rh, rw), cum.sum(lh, l, k, rw)}));
                        }
                    }
                }
            }
        } else {
            assert(0);
        }
        return res;
    };
    cout << func(func, 0, 0, H, W, N) << '\n';
}
accuracy: 1
time_ms: 2800
memory_kb: 3596
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

#pragma GCC ("avx2")
#pragma GCC ("O3")
#pragma GCC ("unroll-loops")

template<class T>
bool chmax(T &a, const T &b) {if (a < b) {a = b; return 1;} return 0;}

using ll = long long;

ll solve1(int x0, int y0, int x1, int y1, const vector<vector<ll>> &A, const vector<vector<ll>> &S)
{
    return S[x1][y1] - S[x1][y0] - S[x0][y1] + S[x0][y0];
}

ll solve2(int x0, int y0, int x1, int y1, const vector<vector<ll>> &A, const vector<vector<ll>> &S)
{
    ll H = A.size(), W = A[0].size();
    
    ll ret = 0;
    for (int h0 = x0; h0 <= x1; ++h0)
    {
        ll a = solve1(x0, y0, h0, y1, A, S);
        ll b = solve1(h0, y0, x1, y1, A, S);
        chmax(ret, min({a, b}));
    }
    for (int w0 = y0; w0 <= y1; ++w0)
    {
        ll a = solve1(x0, y0, x1, w0, A, S);
        ll b = solve1(x0, w0, x1, y1, A, S);
        chmax(ret, min({a, b}));
    }
    
    return ret;
}

ll solve3(int x0, int y0, int x1, int y1, const vector<vector<ll>> &A, const vector<vector<ll>> &S)
{
    ll H = A.size(), W = A[0].size();
    
    
    ll ret = 0;
    for (int h0 = x0; h0 <= x1; ++h0)
    {
        {
            ll a = solve1(x0, y0, h0, y1, A, S);
            ll b = solve2(h0, y0, x1, y1, A, S);
            chmax(ret, min({a, b}));
        }
        {
            ll a = solve2(x0, y0, h0, y1, A, S);
            ll b = solve1(h0, y0, x1, y1, A, S);
            chmax(ret, min({a, b}));
        }
    }
    
    for (int w0 = y0; w0 <= y1; ++w0)
    {
        {
            ll a = solve1(x0, y0, x1, w0, A, S);
            ll b = solve2(x0, w0, x1, y1, A, S);
            chmax(ret, min({a, b}));
        }
        {
            ll a = solve2(x0, y0, x1, w0, A, S);
            ll b = solve1(x0, w0, x1, y1, A, S);
            chmax(ret, min({a, b}));
        }
    }
    
    return ret;
}

ll solve4(int x0, int y0, int x1, int y1, const vector<vector<ll>> &A, const vector<vector<ll>> &S)
{
    ll H = A.size(), W = A[0].size();
    
    
    ll ret = 0;
    for (int h0 = x0; h0 <= x1; ++h0)
    {
        {
            ll a = solve1(x0, y0, h0, y1, A, S);
            ll b = solve3(h0, y0, x1, y1, A, S);
            chmax(ret, min({a, b}));
        }
        {
            ll a = solve2(x0, y0, h0, y1, A, S);
            ll b = solve2(h0, y0, x1, y1, A, S);
            chmax(ret, min({a, b}));
        }
        {
            ll a = solve3(x0, y0, h0, y1, A, S);
            ll b = solve1(h0, y0, x1, y1, A, S);
            chmax(ret, min({a, b}));
        }
    }
    
    for (int w0 = y0; w0 <= y1; ++w0)
    {
        {
            ll a = solve1(x0, y0, x1, w0, A, S);
            ll b = solve3(x0, w0, x1, y1, A, S);
            chmax(ret, min({a, b}));
        }
        {
            ll a = solve2(x0, y0, x1, w0, A, S);
            ll b = solve2(x0, w0, x1, y1, A, S);
            chmax(ret, min({a, b}));
        }
        {
            ll a = solve3(x0, y0, x1, w0, A, S);
            ll b = solve1(x0, w0, x1, y1, A, S);
            chmax(ret, min({a, b}));
        }
    }
    
    for (int h0 = x0; h0 <= x1; ++h0)
    {
        for (int h1 = h0; h1 <= x1; ++h1)
        {
            for (int w0 = y0; w0 <= y1; ++w0)
            {
                for (int w1 = w0; w1 <= y1; ++w1)
                {
                    {
                        ll a = solve1(x0, y0, h0, w1, A, S);
                        ll b = solve1(h0, y0, x1, w0, A, S);
                        ll c = solve1(h1, w0, x1, y1, A, S);
                        ll d = solve1(x0, w1, h1, y1, A, S);
                        chmax(ret, min({a, b, c, d}));
                    }
                    {
                        ll a = solve1(x0, y0, h1, w0, A, S);
                        ll b = solve1(h1, y0, x1, w1, A, S);
                        ll c = solve1(h0, w1, x1, y1, A, S);
                        ll d = solve1(x0, w0, h0, y1, A, S);
                        chmax(ret, min({a, b, c, d}));
                    }
                }
            }
        }
    }
    
    
    return ret;
}

void solve()
{
    ll H, W, N; cin >> H >> W >> N;
    
    vector<vector<ll>> A(H, vector<ll>(W));
    for (int i = 0; i < H; ++i)
    {
        for (int j = 0; j < W; ++j) cin >> A[i][j];
    }
    
    vector<vector<ll>> S(H+1, vector<ll>(W+1, 0));
    for (int i = 0; i < H; ++i)
    {
        for (int j = 0; j < W; ++j)
        {
            S[i+1][j+1] = S[i][j+1] + S[i+1][j] - S[i][j] + A[i][j];
        }
    }
    
    
    ll res = 0;
    if (N == 2)
    {
        res = solve2(0, 0, H, W, A, S);
    }
    else if (N == 3)
    {
        res = solve3(0, 0, H, W, A, S);
    }
    else
    {
        res = solve4(0, 0, H, W, A, S);
    }
    
    cout << res << endl;
    
    return;
}

int main()
{
    solve();
    
    return 0;
}
accuracy: 1
time_ms: 2840
memory_kb: 4120
final_rank: 3

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

int main() {
    int H = in(), W = in(), N = in();
    vector<vector<int>> A = in(H, W);
    vector S(H + 1, vector(W + 1, 0));
    for(int i : rep(H)) for(int j : rep(W)) S[i + 1][j + 1] = A[i][j];
    for(int i : rep(H)) for(int j : rep(W + 1)) S[i + 1][j] += S[i][j];
    for(int i : rep(H + 1)) for(int j : rep(W)) S[i][j + 1] += S[i][j];
    auto F1 = [&](int xL, int xR, int yL, int yR) -> int {
        return S[xR][yR] - S[xL][yR] - S[xR][yL] + S[xL][yL];  
    };

    auto F2 = [&](int xL, int xR, int yL, int yR) -> int {
        int ans = 0;
        for(int xM : rep(xL + 1, xR)) chmax(ans, min(F1(xL, xM, yL, yR), F1(xM, xR, yL, yR)));
        for(int yM : rep(yL + 1, yR)) chmax(ans, min(F1(xL, xR, yL, yM), F1(xL, xR, yM, yR)));
        return ans;
    };

    auto F3 = [&](int xL, int xR, int yL, int yR) -> int {
        int ans = 0;
        for(int xM : rep(xL + 1, xR)) {
            chmax(ans, min(F1(xL, xM, yL, yR), F2(xM, xR, yL, yR)));
            chmax(ans, min(F2(xL, xM, yL, yR), F1(xM, xR, yL, yR)));
        }
        for(int yM : rep(yL + 1, yR)) {
            chmax(ans, min(F1(xL, xR, yL, yM), F2(xL, xR, yM, yR)));
            chmax(ans, min(F2(xL, xR, yL, yM), F1(xL, xR, yM, yR)));
        }
        return ans;
    };

    auto F4 = [&](int xL, int xR, int yL, int yR) -> int {
        int ans = 0;
        for(int xM : rep(xL + 1, xR)) {
            chmax(ans, min(F1(xL, xM, yL, yR), F3(xM, xR, yL, yR)));
            chmax(ans, min(F3(xL, xM, yL, yR), F1(xM, xR, yL, yR)));
            chmax(ans, min(F2(xL, xM, yL, yR), F2(xM, xR, yL, yR)));
        }
        for(int yM : rep(yL + 1, yR)) {
            chmax(ans, min(F1(xL, xR, yL, yM), F3(xL, xR, yM, yR)));
            chmax(ans, min(F3(xL, xR, yL, yM), F1(xL, xR, yM, yR)));
            chmax(ans, min(F2(xL, xR, yL, yM), F2(xL, xR, yM, yR)));
        }
        for(int xLL : rep(xL + 1, xR)) for(int xRR : rep(xLL + 1, xR)) {
            for(int yLL : rep(yL + 1, yR)) for(int yRR : rep(yLL + 1, yR)) {
                chmax(ans, min({F1(xL, xLL, yL, yRR), F1(xL, xRR, yRR, yR), F1(xRR, xR, yLL, yR), F1(xLL, xR, yL, yLL)}));
                chmax(ans, min({F1(xL, xRR, yL, yLL), F1(xRR, xR, yL, yRR), F1(xLL, xR, yRR, yR), F1(xL, xLL, yLL, yR)}));
            }
        }
        return ans;
    };

    if(N == 2) return print(F2(0, H, 0, W));
    if(N == 3) return print(F3(0, H, 0, W));
    if(N == 4) return print(F4(0, H, 0, W));
}
accuracy: 1
time_ms: 2230
memory_kb: 3772
final_rank: 1

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

template < class T > vector< T >& operator++(vector< T >& a) { for(T& x : a) x++; return a; }
template < class T > vector< T >& operator--(vector< T >& a) { for(T& x : a) x--; return a; }
template < class T > vector< T >  operator++(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x++; return res; }
template < class T > vector< T >  operator--(vector< T >& a, signed) { vector< T > res = a; for(T& x : a) x--; return res; }

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

int main() {
    int H = in(), W = in(), N = in();
    vector<vector<int>> A = in(H, W);
    vector S(H + 1, vector(W + 1, 0));
    for(int i : rep(H)) for(int j : rep(W)) S[i + 1][j + 1] = A[i][j];
    for(int i : rep(H)) for(int j : rep(W + 1)) S[i + 1][j] += S[i][j];
    for(int i : rep(H + 1)) for(int j : rep(W)) S[i][j + 1] += S[i][j];
    auto F1 = [&](int xL, int xR, int yL, int yR) -> int {
        return S[xR][yR] - S[xL][yR] - S[xR][yL] + S[xL][yL];  
    };

    auto F2 = [&](int xL, int xR, int yL, int yR) -> int {
        int ans = 0;
        for(int xM : rep(xL + 1, xR)) chmax(ans, min(F1(xL, xM, yL, yR), F1(xM, xR, yL, yR)));
        for(int yM : rep(yL + 1, yR)) chmax(ans, min(F1(xL, xR, yL, yM), F1(xL, xR, yM, yR)));
        return ans;
    };

    auto F3 = [&](int xL, int xR, int yL, int yR) -> int {
        int ans = 0;
        for(int xM : rep(xL + 1, xR)) {
            chmax(ans, min(F1(xL, xM, yL, yR), F2(xM, xR, yL, yR)));
            chmax(ans, min(F2(xL, xM, yL, yR), F1(xM, xR, yL, yR)));
        }
        for(int yM : rep(yL + 1, yR)) {
            chmax(ans, min(F1(xL, xR, yL, yM), F2(xL, xR, yM, yR)));
            chmax(ans, min(F2(xL, xR, yL, yM), F1(xL, xR, yM, yR)));
        }
        return ans;
    };

    auto F4 = [&](int xL, int xR, int yL, int yR) -> int {
        int ans = 0;
        const int W = yR - yL;
        for(int xM : rep(xL + 1, xR)) {
            chmax(ans, min(F1(xL, xM, yL, yR), F3(xM, xR, yL, yR)));
            chmax(ans, min(F3(xL, xM, yL, yR), F1(xM, xR, yL, yR)));
            chmax(ans, min(F2(xL, xM, yL, yR), F2(xM, xR, yL, yR)));
        }
        for(int yM : rep(yL + 1, yR)) {
            chmax(ans, min(F1(xL, xR, yL, yM), F3(xL, xR, yM, yR)));
            chmax(ans, min(F3(xL, xR, yL, yM), F1(xL, xR, yM, yR)));
            chmax(ans, min(F2(xL, xR, yL, yM), F2(xL, xR, yM, yR)));
        }
        for(int xLL : rep(xL + 1, H)) for(int xRR : rep(xLL + 1, H)) {
            for(int yLL : rep(yL + 1, W)) for(int yRR : rep(yLL + 1, W)) {
                chmax(ans, min({F1(xL, xLL, yL, yRR), F1(xL, xRR, yLL, yR), F1(xRR, xR, yLL, yR), F1(xLL, xR, yL, yRR)}));
                chmax(ans, min({F1(xL, xRR, yL, yLL), F1(xRR, xR, yL, yRR), F1(xLL, xR, yRR, yR), F1(xL, xLL, yLL, yR)}));
            }
        }
        return ans;
    };

    if(N == 2) return print(F2(0, H, 0, W));
    if(N == 3) return print(F3(0, H, 0, W));
    if(N == 4) return print(F4(0, H, 0, W));
}
accuracy: 0.23636363636363636
time_ms: 2070
memory_kb: 3692
final_rank: 20

code_snippet: /* -*- coding: utf-8 -*-
 *
 * 2743.cc: Land Inheritance
 */

#include<cstdio>
#include<algorithm>
 
using namespace std;

/* constant */

const int MAX_H = 200;
const int MAX_W = 200;

/* typedef */

/* global variables */

int as[MAX_H][MAX_W], ass[MAX_H + 1][MAX_W + 1];

/* subroutines */

int area(int i0, int j0, int i1, int j1) {
  return ass[i0][j0] - ass[i1][j0] - ass[i0][j1] + ass[i1][j1];
}

int check2(int i0, int j0, int i1, int j1) {
  int maxs = 0;
  for (int i = i0 + 1; i < i1; i++)
    maxs = max(maxs, min(area(i0, j0, i, j1), area(i, j0, i1, j1)));
  for (int j = j0 + 1; j < j1; j++)
    maxs = max(maxs, min(area(i0, j0, i1, j), area(i0, j, i1, j1)));
  return maxs;
}

int check3(int i0, int j0, int i1, int j1) {
  int maxs = 0;
  for (int i = i0 + 1; i < i1; i++) {
    int a0 = area(i0, j0, i, j1), a1 = area(i, j0, i1, j1);
    maxs = max(maxs, min(a0, check2(i, j0, i1, j1)));
    maxs = max(maxs, min(a1, check2(i0, j0, i, j1)));
  }
  for (int j = j0 + 1; j < j1; j++) {
    int a0 = area(i0, j0, i1, j), a1 = area(i0, j, i1, j1);
    maxs = max(maxs, min(a0, check2(i0, j, i1, j1)));
    maxs = max(maxs, min(a1, check2(i0, j0, i1, j)));
  }
  return maxs;
}

int check4(int i0, int j0, int i1, int j1) {
  int maxs = 0;
  for (int i = i0 + 1; i < i1; i++) {
    int a0 = area(i0, j0, i, j1), a1 = area(i, j0, i1, j1);
    maxs = max(maxs, min(a0, check3(i, j0, i1, j1)));
    maxs = max(maxs, min(a1, check3(i0, j0, i, j1)));
    maxs = max(maxs, min(check2(i0, j0, i, j1), check2(i, j0, i1, j1)));
  }
  for (int j = j0 + 1; j < j1; j++) {
    int a0 = area(i0, j0, i1, j), a1 = area(i0, j, i1, j1);
    maxs = max(maxs, min(a0, check3(i0, j, i1, j1)));
    maxs = max(maxs, min(a1, check3(i0, j0, i1, j)));
    maxs = max(maxs, min(check2(i0, j0, i1, j), check2(i0, j, i1, j1)));
  }
  
  return maxs;
}

/* main */

int main() {
  int h, w, n;
  scanf("%d%d%d", &h, &w, &n);
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++) {
      scanf("%d", as[i] + j);
      ass[i + 1][j + 1] =
	as[i][j] + ass[i + 1][j] + ass[i][j + 1] - ass[i][j];
    }

  int maxs = 0;
  if (n == 2) {
    maxs = check2(0, 0, h, w);
  }
  else if (n == 3) {
    maxs = check3(0, 0, h, w);
  }
  else if (n == 4) {
    maxs = check4(0, 0, h, w);
  }

  printf("%d\n", maxs);

  return 0;
}
accuracy: 0.8181818181818182
time_ms: 100
memory_kb: 3276
final_rank: 8