蛋糕
題目大意
把一塊R C的巧克力蛋糕,橫着切三刀,豎着切三刀,共分成16份,然後每次拿最大的那一塊,求出最後那一塊最大的情況
輸入
一行,R 和 C
輸出
最後拿到的蛋糕最多可以有多少巧克力
輸入樣例
5 5
95998
21945
23451
99798
74083
輸出樣例
3
解題思路
這道題聽大佬說是二分答案
就是先枚舉豎的(當然也可以枚舉橫的),然後再二分每一行是否爲成立的,即可算出最優答案
程序如下
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,a[10001][1001],sum,ans,l,r,mid;
bool check(int a1, int a2, int a3, int mid)
{
int p1 = 0, p2 = 0, p3 = 0, p4 = 0, k = 0;
for(int i = 1;i <= n; ++i)
{
p1 += a[i][a1];
p2 += a[i][a2] - a[i][a1];
p3 += a[i][a3] - a[i][a2];
p4 += a[i][m] - a[i][a3];//區間和
if(p1 >= mid && p2 >= mid && p3 >= mid &&p4 >= mid)//判斷是否合理
{
p1 = 0;
p2 = 0;
p3 = 0;
p4 = 0;
k++;
}
}
return k >= 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]);
sum += 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 = sum;
while(l <= r)//二分答案
{
mid = (l + r) >> 1;
if(check(i, j, k, mid)) l = mid + 1;
else r = mid - 1;
}
ans = max(ans, r);
}
}
}
printf("%d",ans);
return 0;
}