【CSP试题回顾】201912-2-回收站选址

文章介绍了两种方法来解决垃圾处理站选址问题,暴力枚举法导致O(N^2*M)的时间复杂度,而优化后的策略仅遍历垃圾点,降低到O(M^2),通过定义trashPoint结构体和邻域邻居检查优化算法效率。

CSP-201912-2-回收站选址

关键点:时间复杂度

1.暴力枚举方法:

  • 暴力枚举方法会遍历二维空间中的每一个点,对于每一个点,检查它的四个直接邻居是否都是垃圾点,然后对于每一个满足条件的点,再检查它的四个对角邻居的垃圾点数量。这种方法的时间复杂度为 O ( N 2 ∗ M ) O(N^2 * M) O(N2M),其中 N 代表二维空间的大小,M 代表垃圾点的数量。这是因为你需要为每个可能的位置检查其周围的八个点是否为垃圾点。

2.优化思路:

  • 本代码采取的策略不是遍历整个二维空间,而是直接遍历垃圾点列表。对于每个垃圾点,代码只检查与这个特定垃圾点相关的邻居(直接和对角线邻居)。这种方法的时间复杂度是 O ( M 2 ) O(M^2) O(M2),其中 M 代表垃圾点的数量。这是因为对于每个垃圾点,你都在检查与它相邻的点是否也是垃圾点,而不是检查整个区域中的每个点。

解题思路

1.数据结构定义

  1. trashPoint 结构体

    • 它包含两个整数变量 xy,分别代表垃圾点在二维空间中的横坐标和纵坐标。
    • 重载的 == 运算符,使得可以直接比较两个 trashPoint 是否具有相同的位置。
  2. vector trashList:用于存储所有输入的垃圾点。

  3. vector pointGrade:用于记录每个等级(0到4对角邻居)的潜在垃圾处理站位置的数量。

2.代码解释:

  1. 输入处理

    • 代码首先从标准输入读取一个整数 n,表示垃圾点的数量。
    • 然后,它循环读取每个垃圾点的坐标 (x, y),并将每个点添加到 trashList 向量中。
  2. 逻辑处理

    • 如果垃圾点数量少于4,按照题目要求,不可能有任何适宜的垃圾处理站位置,因此输出五个0。
    • 如果垃圾点数量大于或等于4,代码进入主要的逻辑处理部分:
      • 对于 trashList 中的每个垃圾点,代码生成其四个直接邻居(上、下、左、右)和四个对角邻居的坐标。
      • 然后,它在 trashList 中搜索这些邻居点,计算直接邻居和对角邻居中垃圾点的数量。
      • 如果一个垃圾点的四个直接邻居都是垃圾点(即这个点周围有四个垃圾点),则它是一个潜在的垃圾处理站位置。
      • 根据这个位置对角相邻的垃圾点数量(0到4个),相应等级的计数增加。

完整代码

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

struct trashPoint
{
	int x, y;
	bool operator==(const trashPoint& other) const {
		return x == other.x && y == other.y;
	}
};
vector<trashPoint>trashList;
vector<int>pointGrade(5);
int n, x, y;

int main()
{
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> x >> y;
		trashList.push_back({ x,y });
	}

	if (n >= 4)
	{
		for (auto& it : trashList)
		{
			trashPoint n1({ it.x,it.y - 1 }), n2({ it.x,it.y + 1 }), n3({ it.x - 1,it.y }), n4({ it.x + 1,it.y });
			trashPoint g1({ it.x + 1, it.y + 1 }), g2({ it.x - 1,it.y - 1 }), g3({ it.x + 1,it.y - 1 }), g4({ it.x - 1,it.y + 1 });
			int findNeighbor = 0, findGrade = 0;
			for (auto& jt : trashList)
			{
				if (jt == n1 || jt == n2 || jt == n3 || jt == n4) findNeighbor++;
				if (jt == g1 || jt == g2 || jt == g3 || jt == g4) findGrade++;
			}
			if (findNeighbor == 4) pointGrade[findGrade]++; // 找到建垃圾站的点it
		}

		for (auto& it : pointGrade) {
			cout << it << endl;
		}
	}
	else
	{
		for (int i = 0; i < 5; i++)
		{
			cout << 0 << endl;
		}
	}
	
	return 0;
}

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值