使用C++的CCF-CSP满分解决方案 202203-2 出行计划

优化算法:高效解决出行计划问题
本文介绍了一种高效的解题方法,避免遍历超时,通过预处理计算任意时刻的可行出行计划,适用于旅行调度问题。展示了C++代码实例,用于n个旅行者在m天内的k天内满足需求的查询计数。

在这里插入图片描述

注意事项

不能采取遍历的方式,这样会超时,正确的解法是预处理,求出任意时刻的,可满足的出行计划。

满分代码实现

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

class Solution {
   
   
private:
	int MAXDAYS = 2000001;
public:
	void solve();
};

void Solution
### 解题思路 本题的目的是判断绿化图中是否存在与藏宝图完全匹配的区域。匹配的条件是:藏宝图中的每个 `1` 的位置在绿化图中也必须是 `1`,并且藏宝图不能超出绿化图的边界。 #### 数据结构与算法选择 - **二维数组**:使用二维数组存储绿化图和藏宝图。 - **暴力枚举**:枚举绿化图中每个点作为藏宝图左下角的可能位置,然后检查藏宝图是否能完全匹配。 - **优化检查**:通过提前记录藏宝图中 `1` 的数量,以及在匹配过程中统计匹配成功的 `1` 数量,减少不必要的计算。 ### C++ 满分代码实现 ```cpp #include <iostream> #include <vector> using namespace std; int main() { int n, L, S; cin >> n >> L >> S; // 存储绿化图中的点 vector<vector<int>> A(L + 1, vector<int>(L + 1, 0)); for (int i = 0; i < n; ++i) { int x, y; cin >> x >> y; A[x][y] = 1; } // 存储藏宝图 vector<vector<int>> B(S + 1, vector<int>(S + 1, 0)); for (int i = S; i >= 0; --i) { for (int j = 0; j <= S; ++j) { cin >> B[i][j]; } } int count = 0; // 枚举绿化图中每个点作为藏宝图的左下角 for (int x = 0; x <= L; ++x) { for (int y = 0; y <= L; ++y) { bool match = true; int match_count = 0; int target_count = 0; // 统计藏宝图中1的总数 for (int i = 0; i <= S; ++i) { for (int j = 0; j <= S; ++j) { if (B[i][j] == 1) { target_count++; } } } // 检查藏宝图是否可以匹配绿化图 for (int i = 0; i <= S; ++i) { for (int j = 0; j <= S; ++j) { if (B[i][j] == 1) { if (x + i > L || y + j > L || A[x + i][y + j] != 1) { match = false; break; } match_count++; } } if (!match) break; } if (match && match_count == target_count) { count++; } } } cout << count << endl; return 0; } ``` ### 代码解析 1. **输入处理**:首先读取输入数据,包括绿化图的点、藏宝图的大小和内容。 2. **匹配检查**:通过双重循环枚举绿化图中每个点作为藏宝图的左下角,然后检查藏宝图是否能完全匹配。 3. **效率优化**: - 提前统计藏宝图中 `1` 的数量。 - 在匹配过程中,一旦发现不匹配的情况立即跳出循环- 只有当匹配成功的 `1` 数量与藏宝图中的 `1` 数量相等时,才认为匹配成功。 ### 时间复杂度分析 - **枚举复杂度**:`O(L^2)`,其中 `L` 是绿化图的大小。 - **匹配复杂度**:`O(S^2)`,其中 `S` 是藏宝图的大小。 - **总复杂度**:`O(L^2 * S^2)`,在数据范围内是可接受的。 ### 空间复杂度分析 - 使用两个二维数组存储绿化图和藏宝图,空间复杂度为 `O(L^2 + S^2)`。 ### 测试用例与边界条件 - **边界条件**:确保藏宝图不会超出绿化图的边界。 - **测试用例**:包括多个藏宝图和绿化图的组合,验证代码的正确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值