题面
问题描述
给定一个二维整数数组
𝑋
,数组中每个元素取值的范围为
[0,255]
。按照以下函数对二维数组
进行滤波处理,输出滤波后的二维数组
𝑌
。
记该二维数组大小为
𝑁 × 𝑁
,记
表示该二维数组第
𝑖
行第
𝑗
列的元素,记
表示输出二维
数组第
𝑖
行第
𝑗
列的元素,
𝑖 ∈ {0,1,… , 𝑁 − 1}
,
𝑗 ∈ {0,1, … , 𝑁 − 1}
。
首先通过如下函数获得:
注意:
1.
当
𝑥
𝑖+𝑘,𝑗+𝑘
超出
X
数组边界时按照取
0
处理,例
𝑥
−1,0
超出
X
数组边界则
𝑥
−1,0
按照取
0
处理。
2.
𝑦
𝑖,𝑗
按照上述函数处理后,要求四舍五入取整输出。
输入格式
输入的第一行包含一个整数
N
,表示二维数组
𝑋
的大小。
输入的第二行包含
𝑁 × 𝑁
个整数,每个数的取值范围为
[0,255]
,相邻的整数之间用一个空格
分隔。
输出格式
输出
N
行
N
列的二维数组,每个元素为整数,不同元素之间用一个空格分隔,不同行之间
用换行符分隔。
样例输入
2
9 9 9 9
样例输出
4 4
4 4
样例说明
2
为
N
的值,即
X
应为
2
×
2
的数组,
X
的四个元素分别为
9,9,9,9
,
i
的取值范围为
{0,1,2,3}
,
j
的取值范围为
{}0,1,2,3}
。
评测用例规模与约定
1
≤
N
≤
1000
题解
题目分析
本题体面很长,但是可以简化为计算每个3*3区域内平均数并输出
技巧
我想出了一个很好的方法避免数组越界:让数组从1开始记录数值
具体说明一下原理:当行、列开头时,因为坐标是1,所以计算3*3的区域时会使用坐标0而不会越界
如下表所示
列 | ||||||||
---|---|---|---|---|---|---|---|---|
行 | 0 | 1 | 2 | 3 | ||||
0 | 0 | 0 | 0 | 0 | ||||
1 | 0 | 9 | 9 | 0 | ||||
2 | 0 | 9 | 9 | 0 | ||||
3 | 0 | 0 | 0 | 0 |
思路
- 用二维数组存储矩阵
- 算出3*3区域内的数字和,之后计算平均数(注意四舍五入的问题)
- 按格式输出注意空格和换行
满分代码(含注释)
#include <iostream>
#include <cmath>
using namespace std;
int n; // n行n列
double tmpsum; // 临时和
int a[1010][1010]; // 二维数组
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> a[i][j];
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
tmpsum = 0; // 初始化临时和
for (int k = i - 1; k <= i + 1; k++)
{
for (int l = j - 1; l <= j + 1; l++)
{
tmpsum += a[k][l]; // 计算当前3*3区域内的数字和
}
}
cout << round (tmpsum / 9) << ' '; // 四舍五入输出平均数
}
cout << '\n';
}
return 0;
}
纯享版代码(不含注释)
#include <iostream>
#include <cmath>
using namespace std;
int n;
double tmpsum;
int a[1010][1010];
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> a[i][j];
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
tmpsum = 0;
for (int k = i - 1; k <= i + 1; k++)
{
for (int l = j - 1; l <= j + 1; l++)
{
tmpsum += a[k][l];
}
}
cout << round (tmpsum / 9) << ' ';
}
cout << '\n';
}
return 0;
}
date:20240104