题目描述
给你一个 H * W 的矩阵,每个单元格内包含一个不大于 N 的数,再给一个小矩阵 h * w,从左上角开始一次移动一格,直到右下角与大矩阵边缘重合时结束。请你求出他在每个点围成的小矩阵之外所有单元格的数字种类个数总和。
解题思路
我们发现题目的数据给的很小,甚至可以(N ^ 3)。所以我们想到,单独统计矩阵内某一个数字的个数就是用二维前缀和维护的,得到矩阵外的个数也就是直接拿右下角的最大前缀和,减去维护的矩阵就可以了。接下来我们推广一下,对每个数字都这样维护一个二维前缀和,也就多了一维。
代码示例
#include<bits/stdc++.h>
using namespace std;
int H, W, N, h, w;
int mp[310][310];
int a[310][310][310];
int sum[310][310][310];
int main(){
cin >> H >> W >> N >> h >> w;
for(int i = 1; i <= H; i++){
for(int j = 1; j <= W; j++){
cin >> mp[i][j];
a[i][j][mp[i][j]] = 1;
}
}
for(int i = 1; i <= H; i++){
for(int j = 1; j <= W; j++){
for(int k = 1; k <= N; k++){
sum[i][j][k] = sum[i][j][k] + a[i][j][k] + sum[i - 1][j][k] + sum[i][j - 1][k] - sum[i - 1][j - 1][k];
}
}
}
int ans = 0;
for(int i = h; i <= H; i++){
for(int j = w; j <= W; j++){
ans = 0;
for(int k = 1; k <= N; k++){
ans += sum[H][W][k] - (sum[i][j][k] - sum[i][j - w][k] - sum[i - h][j][k] + sum[i - h][j - w][k]) != 0;
}
cout << ans << " ";
}
cout << endl;
}
system("pause");
}