题目大意:
有一个 n ∗ m n*m n∗m的蛋糕(有数字),横着切三刀在竖着切三刀分成16份使最小的最大。
思路:
首先“最小的最大”确定了这题可以二分答案
这题我们先暴枚竖切三刀,再二分判定
C o d e Code Code:
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int n,m,rr,ans,l,r;
int a[1001][1001];
bool check (int i,int j,int k,int mid)//判定能不能
{
int o1 = 0, o2 = 0, o3 = 0 ,o4 = 0 ,kk = 0;
for (int sum = 1; sum <= n; ++sum)
{
o1 += a[sum][i];
o2 += a[sum][j] - a[sum][i];
o3 += a[sum][k] - a[sum][j];
o4 += a[sum][m] - a[sum][k];//求矩阵
if(o1 >= mid && o2 >= mid && o3 >= mid && o4 >= mid)
{
o1 = 0;
o2 = 0;
o3 = 0;
o4 = 0;
kk++;
}
}
return kk >= 4;
}
int main ()
{
scanf ("%d%d", &n, &m);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
{
scanf("%1d",&a[i][j]);
rr += a[i][j];//先加上矩阵
a[i][j] += a[i][j - 1];//前缀
}
for (int i = 1; i <= m; ++i) //暴力
for (int j = i + 1; j <= m; ++j)
for (int k = j + 1; k <= m; ++k)
{
l = 0, r = rr; //左右
while(l <= r)//二分答案
{
int mid = (l + r) / 2;//中
if (check(i, j, k, mid)) l = mid + 1;
else r = mid - 1;
}
ans = max (ans,r);//答案
}
printf("%d",ans);
}