【CSP试题回顾】202104-2-邻域均值(优化)

CSP-202104-2-邻域均值

关键点:二维前缀和数组

详见:

解题思路

1.输入和初始化

  • 首先,程序从输入中获取四个整数n(矩阵的大小),L(像素亮度的上限),r(局部区域的半径)和t(暗像素判定阈值)。初始化一个n x n的二维数组pic来存储输入的图像数据(每个像素的亮度值)。

2.构建二维前缀和数组:

  1. 初始化前缀和数组:

    • 首先,initPrefixSum函数创建一个大小为(n+1) x (n+1)的新数组prefixSum,所有元素初始化为0。这个大小比原图像多一行和一列是为了方便边界情况的处理,避免在计算时出现索引越界。
    • 这个额外的行和列代表的是边界外的空区域,其前缀和自然为0。
  2. 填充前缀和数组:

    • 然后,函数遍历原始的图像数组pic。对于图像中的每个像素(i-1, j-1)(因为我们的prefixSum是从1开始计数的,所以原图像的第一个元素对应于prefixSum(1, 1)),更新prefixSum数组。
    • 更新规则如下:prefixSum[i][j]的值等于当前元素matrix[i - 1][j - 1](即原图像的当前像素亮度值),加上左侧元素的前缀和prefixSum[i][j-1],加上上方元素的前缀和prefixSum[i-1][j],再减去左上角元素的前缀和prefixSum[i-1][j-1],因为它被加了两次。
    • 通过这种方式,每个prefixSum[i][j]代表了原始图像左上角到(i-1, j-1)形成的矩形区域的所有像素亮度之和。

3.判断暗像素:

  1. 遍历图像中的每个像素:

    • isDark函数用于确定一个像素是否“暗”。对于图像中的每个像素(i, j),函数计算以该像素为中心,边长为2r+1的局部区域内所有像素的平均亮度。
    • 要考虑边界条件,即当像素位于图像的边缘时,实际的局部区域可能小于2r+1。因此,实际的局部区域边界由max(0, i - r)max(0, j - r)min(n - 1, i + r)min(n - 1, j + r)确定。
  2. 计算局部区域亮度平均值:

    • 使用前缀和数组,可以快速计算局部区域的总亮度:这是通过查询前缀和数组中相应角落的值并应用矩形区域和公式来完成的。
    • 计算该区域内的像素总数,即(xEnd - xStart + 1) * (yEnd - yStart + 1)
    • 计算平均亮度,即区域总亮度除以区域内的像素总数。
    • 如果这个平均亮度小于或等于阈值t,则认为中心像素是“暗”的。

4.统计和输出结果

  • 在遍历过程中,统计被认为是“暗”的像素的数量。最后,输出“暗”像素的总数。

完整代码

【100分思路-前缀和数组】

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int n, L, r, t, darkNum;
vector<vector<int>>pic, prefixSum;

void initPrefixSum(vector<vector<int>>& prefixSum, const vector<vector<int>>& matrix) {
	int rows = matrix.size();
	int cols = matrix[0].size();
	prefixSum.resize(rows + 1, vector<int>(cols + 1, 0));

	for (int i = 1; i <= rows; ++i) {
		for (int j = 1; j <= cols; ++j) {
			prefixSum[i][j] = matrix[i - 1][j - 1]
				+ prefixSum[i - 1][j]
				+ prefixSum[i][j - 1]
				- prefixSum[i - 1][j - 1];
		}
	}
}

int queryPrefixSum(const vector<vector<int>>& prefixSum, int x1, int y1, int x2, int y2) {
	int sum = prefixSum[x2 + 1][y2 + 1]
		- prefixSum[x1][y2 + 1]
		- prefixSum[x2 + 1][y1]
		+ prefixSum[x1][y1];
	return sum;
}

bool isDark(int i, int j) {
	int xStart = max(0, i - r), yStart = max(0, j - r);
	int xEnd = min(n - 1, i + r), yEnd = min(n - 1, j + r);
	double sum = queryPrefixSum(prefixSum, xStart, yStart, xEnd, yEnd);
	double num = (xEnd - xStart + 1) * (yEnd - yStart + 1);
	double arg = sum / num;
	return arg <= t;
}

int main() {
	cin >> n >> L >> r >> t;
	pic = vector<vector<int>>(n, vector<int>(n, 0));
	for (auto& it : pic) {
		for (auto& jt : it) {
			cin >> jt;
		}
	}

	initPrefixSum(prefixSum, pic); // 构建二维前缀和数组

	for (size_t i = 0; i < pic.size(); i++)
	{
		for (size_t j = 0; j < pic[i].size(); j++)
		{
			if (isDark(i, j)) darkNum++;
		}
	}
	cout << darkNum;
    return 0;
}

【70分思路-暴力枚举】

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int n, L, r, t, darkNum;
vector<vector<int>>pic;

bool isDark(int i, int j) {
	int xStart = max(0, i - r), yStart = max(0, j - r);
	int xEnd = min(n - 1, i + r), yEnd = min(n - 1, j + r);
	double num = 0, sum = 0;

	for (size_t x1 = xStart; x1 <= xEnd; x1++)
	{
		for (size_t y1 = yStart; y1 <= yEnd; y1++)
		{
			num++;
			sum += pic[x1][y1];
		}
	}

	double arg = sum / num;
	return arg <= t;
}


int main() {
	cin >> n >> L >> r >> t;
	pic = vector<vector<int>>(n, vector<int>(n, 0));
	for (auto& it : pic) {
		for (auto& jt : it) {
			cin >> jt;
		}
	}
	for (size_t i = 0; i < pic.size(); i++)
	{
		for (size_t j = 0; j < pic[i].size(); j++)
		{
			if (isDark(i, j)) darkNum++;
		}
	}
	cout << darkNum;
    return 0;
}

相关推荐

  1. CSP试题回顾202104-2-均值优化

    2024-03-27 05:36:07       40 阅读
  2. ccf 202104-2 均值

    2024-03-27 05:36:07       39 阅读
  3. CSP试题回顾】202303-2-垦田计划(优化

    2024-03-27 05:36:07       50 阅读
  4. CSP试题回顾】202209-2-何以包邮?(优化

    2024-03-27 05:36:07       36 阅读
  5. CSP试题回顾】201912-2-回收站选址(优化

    2024-03-27 05:36:07       39 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-27 05:36:07       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-27 05:36:07       101 阅读
  3. 在Django里面运行非项目文件

    2024-03-27 05:36:07       82 阅读
  4. Python语言-面向对象

    2024-03-27 05:36:07       91 阅读

热门阅读

  1. 大话设计模式之工厂模式

    2024-03-27 05:36:07       43 阅读
  2. 【node】Missing script start or file server.js

    2024-03-27 05:36:07       39 阅读
  3. 蓝桥杯:BFS

    2024-03-27 05:36:07       34 阅读
  4. Unity3D 主城角色动画控制与消息触发详解

    2024-03-27 05:36:07       38 阅读
  5. 约瑟夫环-递推公式的个人理解

    2024-03-27 05:36:07       39 阅读
  6. 计算机网络(04)

    2024-03-27 05:36:07       44 阅读
  7. C# get set 访问器

    2024-03-27 05:36:07       36 阅读
  8. 智能媒体api调用

    2024-03-27 05:36:07       41 阅读
  9. C#语言规范及特殊用法笔记

    2024-03-27 05:36:07       45 阅读