题解:P10719 [GESP202406 五级] 黑白格

· · 题解

解题思路

注意到 n,m\le 100,可以 O(n^4) 枚举每个子矩形的左上角 (x_1,y_1) 和右下角 (x_2,y_2)

利用二维 前缀和 O(1) 计算每个子矩形中黑色格子数量,维护包含至少 k 个黑色格矩形的面积最小值。

\begin{cases} a_{i,j}=b_{i,j}+a_{i-1,j}+a_{i,j-1}-a_{i-1,j-1} \\ t=\sum_{i=x_1}^{x_2}\sum_{j=y_1}^{y_2}p_{i,j}=a_{x_2,y_2}-a_{x_1-1,y_2}-a_{x_2,y_1-1}+a_{x_1-1,y_1-1} \\ s=(x_2-x_1+1)(y_2-y_1+1) \end{cases}

特别地,如果不存在输出 0

参考代码

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

const int inf=0x3f3f3f3f;
const int N=105;
int a[N][N];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n,m,k;
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            char f;
            cin>>f;
            a[i][j]=f-'0'+a[i-1][j]+a[i][j-1]-a[i-1][j-1];
        }
    }
    int ans=inf;
    for(int x1=1;x1<=n;x1++)
    {
        for(int y1=1;y1<=m;y1++)
        {
            for(int x2=x1;x2<=n;x2++)
            {
                for(int y2=y1;y2<=m;y2++)
                {
                    int s=a[x2][y2]-a[x1-1][y2]-a[x2][y1-1]+a[x1-1][y1-1];
                    if(s>=k)ans=min(ans,(x2-x1+1)*(y2-y1+1));
                }
            }
        }
    }
    cout<<(ans!=inf?ans:0)<<'\n';
    return 0;
}