洛谷P8783 [蓝桥杯 2022 省 B] 统计子矩阵

题目描述

给定一个 N×M 的矩阵 A,请你统计有多少个子矩阵 (最小 1×1, 最大 N×M) 满足子矩阵中所有数的和不超过给定的整数 K。

输入格式

第一行包含三个整数 N,M 和 K。

之后 N 行每行包含 M 个整数, 代表矩阵 A。

输出格式

一个整数代表答案。

输入输出样例

输入 

3 4 10
1 2 3 4
5 6 7 8
9 10 11 12

输出 

19

说明/提示

【样例说明】

满足条件的子矩阵一共有 19,包含:

大小为 1×1 的有 10 个。

大小为 1×2 的有 3 个。 大小为 1×3 的有 2 个。

大小为 1×4 的有 1 个。

大小为 2×1 的有 3 个。

【评测用例规模与约定】

对于 30% 的数据, N,M≤20.

对于 70% 的数据, N,M≤100.

对于 100% 的数据, 1≤N,M≤500,0≤Aij​≤1000,1≤K≤2.5×108.

蓝桥杯 2022 省赛 B 组 F 题。
P8783 [蓝桥杯 2022 省 B] 统计子矩阵 - 洛谷


这题我运用二维前缀和公式和然后利用计算子矩阵和公式解决这题,但只得了80分


使用二维前缀和,用 sum[i][j] 表示矩阵中 x∈[1,i],y∈[1,j] 的所有元素之和。其递推式为 sum[i][j]=sum[i−1][j]+sum[i][j−1]−sum[i−1][j−1]+arr[i][j]

所以矩阵该矩阵的元素之和就可以用 sum[c][d] - sum[c][b - 1] - sum[a - 1][d] + sum[a - 1][b - 1]

 以下是我c语言提交的代码仅供参考:
 

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<limits.h>
#include<stdlib.h>
#include<math.h>
#include <stdbool.h>

int sum[501][501] = { 0 };

//计算二维矩阵中从左上角坐标 (a,b) 到右下角坐标 (c,d) 的子矩阵的和。
int sums(int a, int b, int c, int d)
{
    return sum[c][d] - sum[c][b - 1] - sum[a - 1][d] + sum[a - 1][b - 1];
}
int main() 
{
    int n, m, k = 0; int count = 0;
    int arr[501][501] = { 0 };

    scanf("%d %d %d", &n, &m,&k);

    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            scanf("%d", &arr[i][j]);
        }
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            //二维前缀和计算
            sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + arr[i][j];
        }
    }

    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            for (int x = i; x <= n; x++)
            {
                for (int y = j; y <= m; y++)
                {
                    if (sums(i, j, x, y) <= k)
                    {
                        count++;
                    }
                }

            }
        }
    }

    printf("%d\n", count);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值