# 题目描述

在卷积神经网络(CNN)中,最大池化是一种常用的操作,用来对特征图进行降采样,从而减少数据量和计算量。最大池化会在特征图的每个区域中选取最大值作为该区域的代表值。

给定一个大小为 n×mn \times m 的矩阵和一个池化窗口的大小 p×qp \times q,你需要对这个矩阵进行最大池化操作,即将矩阵划分为若干个 p×qp \times q 的区域,并从每个区域中选取最大值,生成一个新的池化矩阵,具体的生成过程可参考样例解释。

# 输入格式

第一行包含四个整数 n,m,p,qn, m, p, q,分别表示矩阵的行数、列数以及池化窗口的行数和列数(2pn100,2qm1002 \le p \le n \le 100, 2 \le q \le m \le 100,且 nnpp 的整数倍,mmqq 的整数倍)。

接下来 nn 行,每行包含 mm 个整数,表示矩阵中的元素值,保证元素值在 int 范围内。

# 输出格式

输出一个新的矩阵,表示经过 p×qp \times q 大小的最大池化操作后得到的池化矩阵。矩阵的同一行的相邻元素之间用一个空格隔开。

# 样例输入

4 4 2 2
1 3 2 4
5 6 7 8
9 10 11 12
13 14 15 16

# 样例输出

6 8
14 16

# 样例解释

得到池化矩阵的过程如下图:

池化矩阵样例

# 题解:模拟

用二维数组存下,直接依题意模拟即可。参考代码如下:

#include <stdio.h>
#include <math.h>
#include <limits.h>
int n, m, p, q, mat[105][105];
int main()
{
    // freopen("D.in", "r", stdin);
    // freopen("D.out", "w", stdout);
    scanf("%d%d%d%d", &n, &m, &p, &q);
    for (int i = 1; i <= n; ++ i)
        for (int j = 1; j <= m; ++ j)
            scanf("%d", &mat[i][j]);
    
    for (int i = 1; i <= n; i += p)
    {
        for (int j = 1; j <= m; j += q)
        {
            int max = INT_MIN;
            for (int u = i; u <= i + p - 1; ++ u)
                for (int v = j; v <= j + q - 1; ++ v)
                    max = fmax(max, mat[u][v]);
            
            printf("%d ", max);
        }
        puts("");
    }
    return 0;
}