测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A32251. 黑白格题面描述小杨有一个n行m列的网格图,其中每个格子要么是白色,要么是黑色。小杨想知道至少包含k个黑色格子的最小子矩形包含了多少个格子。

填空题 困难

题目描述

黑白格

题面描述

小杨有一个n行m列的网格图,其中每个格子要么是白色,要么是黑色。

小杨想知道至少包含k个黑色格子的最小子矩形包含了多少个格子。

输入格式

第一行包含三个正整数 n,m,k,含义如题面所示。

之后n行,每行一个长度为m的01串,代表网格图第i行格子的颜色,如果为0,则对应格子为白色,否则为黑色。

输出格式

输出一个整数,代表至少包含k个黑色格子的最小子矩形包含格子的数量,如果不存在则输0。

样例1

输入

4 5 5

00000

01111

00011

00011

输出

6

样例解释

对于样例1,假设(i,j) 代表第i行第k列,至少包含5个黑色格子的最小子矩形的四个顶点为 (2,4),(2,5),(4,4),(4,5),共包含6个格子。

数据范围

 

对于全部数据,保证有 1 ≤ n,m ≤ 100, 1 ≤ k ≤  n * m 。

参考答案

#include<bits/stdc++.h> using namespace std; const int N = 110; int w[N][N]; int sum[N][N]; int n,m; int main() { int k; cin>>n>>m>>k; for(int i=1; i<=n; i++) { string s; cin>>s; for(int j=1; j<=m; j++) { w[i][j]=s[j-1]-'0'; sum[i][j]=sum[i][j-1]+w[i][j]; } } int ans = 0; for(int i=1; i<=m; i++) { for(int j=i; j<=m; j++) { vector<int> num; int now = 0; for(int l=1; l<=n; l++) { int tmp = sum[l][j]-sum[l][i-1]; now+=tmp; num.push_back(now); if(now>=k) { if(ans ==0)ans=(j-i+1)*l; else ans=min(ans,(j-i+1)*l); int L=1,R=l; while (L < R) { int mid = L + R + 1 >> 1; if (now-num[mid-1]>=k) L = mid; else R = mid - 1; } if(now-num[L-1]>=k) { if(ans ==0)ans=(j-i+1)*(l-L); else ans=min(ans,(j-i+1)*(l-L)); } } } } } cout<<ans<<"\n"; }
上一题 下一题