洛谷 B4415:[GESP202509 四级] 排兵布阵 ← 暴力枚举法

【题目来源】
https://www.luogu.com.cn/problem/B4415

【题目描述】
作为将军,你自然需要合理地排兵布阵。地图可以视为 n 行 m 列的网格,适合排兵的网格以 1 标注,不适合排兵的网格以 0 标注。现在你需要在地图上选择一个矩形区域排兵,这个矩形区域内不能包含不适合排兵的网格。请问可选择的矩形区域最多能包含多少网格?

【输入格式】
第一行,两个正整数 n,m,分别表示地图网格的行数与列数。
接下来 n 行,每行 m 个整数 ai,1, ai,2, …, ai,m,表示各行中的网格是否适合排兵。

【输出格式】
一行,一个整数,表示适合排兵的矩形区域包含的最大网格数。

【输入样例一】
4 3
0 1 1
1 0 1
0 1 1
1 1 1

【输出样例一】
4

【输入样例二】
3 5
1 0 1 0 1
0 1 0 1 0
0 1 1 1 0

【输出样例二】
3

【数据范围】
对于所有测试点,保证 1≤n,m≤12,0≤ai,j≤1。

【算法分析】
由于数据规模较小(1≤n,m≤12),可以采用暴力枚举法求解。具体思路是枚举所有可能的矩形区域,检查该区域是否全部为1,然后记录最大面积。

【算法代码】

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

const int maxn=15;
int a[maxn][maxn];
int n,m,ans;

int cal(int u,int v) {
    int w=m; //min_width
    for(int i=u; i<=n; i++) {
        for(int j=v; j<=w; j++) {
            if(a[i][j]==0) {
                w=j-1;
                break;
            } else {
                int t=(i-u+1)*(j-v+1);
                if(t>ans) ans=t;
            }
        }
    }
    return ans;
}

int main() {
    cin>>n>>m;
    for(int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++) {
            cin>>a[i][j];
        }
    }

    for(int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++) {
            if(a[i][j]!=0) cal(i,j);
        }
    }

    cout<<ans;

    return 0;
}

/*
in:
3 5
1 0 1 0 1
0 1 0 1 0
0 1 1 1 0

out:
3
*/





【参考文献】
https://www.bilibili.com/video/BV1ia4uziEEc/
https://blog.csdn.net/mtm001/article/details/153044086
https://gesp.ccf.org.cn/101/attach/1703973044092960.pdf
https://www.luogu.com.cn/problem/solution/B4415

 

posted @ 2025-11-19 14:32  Triwa  阅读(54)  评论(0)    收藏  举报