P1649 Obstacle Course S(dfs卡方向数组/bfs)

传送门icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P1649

开始拿到题,发现数据范围是100,于是我尝试用dfs一做,写完后发现是90分,TLE一个点。于是乎观看题解(我还以为能剪枝掉),发现改一下遍历方向就能过了(我认为是数据不好)

大概是有其他的优化方法的(

dfs代码(90分/100分)

// Problem: 
//     P1649 [USACO07OCT] Obstacle Course S
//   
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1649
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<iostream>
using namespace std;
const int N=105;
int n;
char a[N][N];
int vis[N][N];
int sx,sy,ex,ey;
int minn=1e9;
int dx[4]={1,0,-1,0};
int dy[4]={0,-1,0,
<think>好的,我现在需要帮用户改进他们提供的C++代码,使用BFS算法和洪水填充思想,同时结合queue和struct进行优化。首先,我得仔细看看用户提供的现有代码和他们的需求。 用户给出的引用[3]中的代码是用数组模拟队列实现的BFS,用于计算马走日的距离。现在他们想改用STL的queue和struct来优化代码结构,这可能让代码更简洁易懂。首先,我需要理解原代码的结构。原代码中使用了一个PII类型的数组q来模拟队列,hh和tt作为头尾指针。dist数组记录每个位置的距离,初始化为-1,表示未访问。 用户希望用struct代替pair,这样可能增加代码的可读性,因为struct可以有更具描述性的成员变量名,比如x和y。同时,使用STL的queue可以避免手动管理队列的头尾指针,减少出错的可能性。 接下来,我需要将原代码中的PII队列替换为struct和STL queue。原来的PII表示坐标,改为struct Node,包含x和y成员。然后,队列类型改为queue<Node>。同时,访问队列元素的方式需要调整,原来的数组索引改为front()和pop()。 然后检查洪水填充的部分是否正确。BFS本身就是洪水填充的典型应用,逐层扩展。需要确保每个节点的邻居被正确访问,距离更新正确。原代码中的dx和dy数组是8个方向,对应马的日字形移动,所以洪水填充的范围是按这个方式扩散的。 另外,原代码中的dist初始化是-1,表示未访问,这在修改后的代码中应该保持一致。入队时设置dist为0,然后每次从队列取出节点,遍历8个方向,计算新的坐标,判断是否在边界内且未被访问过,如果是,则设置距离并入队。 需要注意的点包括:struct的定义是否正确,STL queue的使用是否正确,比如是否包含头文件<queue>,是否正确处理了队列的push和pop操作。同时,检查数组越界的问题,比如a和b的范围是否在1到n和1到m之间。 可能还需要测试修改后的代码是否和原代码功能一致,比如输出每个位置的最短距离是否正确。例如,当n和m较大时,是否会出现性能问题,但使用STL queue通常不会有问题,因为BFS的时间复杂度主要取决于节点数量,而STL的queue操作是常数时间的。 最后,确保代码风格整洁,struct命名清晰,注释到位,方便用户理解和进一步修改。可能还需要对比原代码,确保所有逻辑都被正确转换,比如初始化队列、距离数组的处理,以及遍历方向的循环等。</think>### 改进后的BFS算法实现(结合洪水填充与结构体优化) ```cpp #include <bits/stdc++.h> using namespace std; const int N = 1e3 + 10; // 定义坐标结构体提升可读性 struct Node { int x, y; }; int n, m, start_x, start_y; int dist[N][N]; int dx[] = {-2, -1, 1, 2, 2, 1, -1, -2}; // 8个移动方向 int dy[] = {1, 2, 2, 1, -1, -2, -2, -1}; void bfs_optimized(int x, int y) { queue<Node> q; // 使用STL队列 memset(dist, -1, sizeof dist); q.push({x, y}); dist[x][y] = 0; while (!q.empty()) { auto t = q.front(); // 获取队首元素 q.pop(); // 弹出队首 for (int i = 0; i < 8; ++i) { int a = t.x + dx[i]; int b = t.y + dy[i]; if (a >= 1 && a <= n && b >= 1 && b <= m && dist[a][b] == -1) { dist[a][b] = dist[t.x][t.y] + 1; q.push({a, b}); // 新坐标入队 } } } } int main() { scanf("%d%d%d%d", &n, &m, &start_x, &start_y); bfs_optimized(start_x, start_y); for (int i = 1; i <= n; ++i) { for (int j = 1; j <= m; ++j) { printf("%-5d", dist[i][j]); } putchar('\n'); } return 0; } ``` ### 主要改进点说明 1. **结构体优化**:使用`Node`结构体替代`pair<int,int>`,增强坐标的可读性[^3] 2. **STL队列**:采用`queue<Node>`替代数组模拟队列,简化代码逻辑 3. **边界判断优化**:合并坐标有效性判断条件 4. **内存管理**:保持原有`dist`数组的初始化方式,确保空间复杂度不变 ### 算法特性 该实现利用BFS的层序扩展特性,实现类似洪水填充的效果。每个网格第一次被访问时即获得最短路径长度,时间复杂度为$O(nm)$,空间复杂度为$O(nm)$,与网格面积成正比[^3]。 相关问题
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值