【算法分享】方向迷宫 + 魔法路径判定:BFS 与 0-1 BFS 双解法详解
📖 1. 题目简述
-
你在一个
n × m的矩阵中移动 -
每个格子有一个方向:
U D L R -
你不能随意移动,只能按照格子的方向移动
-
你有 k 次魔法机会,可以修改任意一个格子的方向
-
问:最多用 k 次魔法,是否能从 (1,1) 达到 (n,m)?
很快想到图论模型:每个格子就是图中的节点,不同方向有不同代价!这其实是一个典型的 0-1 BFS 最短路径问题。
附上题目链接(牛客网):https://ac.nowcoder.com/acm/contest/115184/D
🎯 2. 解题思路概览。
本题实质是一个图上的最短路径问题,魔法次数就是代价:很快想到图论模型:每个格子就是图中的节点,不同方向有不同代价!这其实是一个典型的 0-1 BFS 最短路径问题。
-
根据方向移动,一步一步进行
-
如果方向正确,移动成功,耗费 0
-
如果方向错误,需要改方向,耗费 1 (使用魔法)
| 点和边 | 说明 |
|---|---|
每个格子 (x, y) |
是一个点 |
从 (x, y) 进行一步移动 |
是一条边 |
| 边权 | 如果方向正确,为 0;否则为 1 |
🧠 3. 核心思想
-
使用 deque 保持两端
-
当耗费 = 0 时,push_front ( 优先执行 )
-
当耗费 = 1 时,push_back
假设我们有如下矩阵:
起点
↓
[ R, D ]
[ U, L ]
↑
终点
对应索引:
(0,0) → R → (0,1)
↓D
(1,1)
原始路径:
-
(0,0) → R → (0,1)
-
(0,1) → D → (1,1)
如果方向正确,一路代价为 0。
修改方向的情形:
- 若 (0,0) 是
U,则必须魔法改为R,代价 1
以此类推。
🛠️ 4. 解法实现:0-1 BFS
deque<pair<int, int>> dq;
dist[0][0] = 0;
dq.emplace_front(0, 0);
// 遍历所有方向
for (int d = 0; d < 4; ++d)
{
int nx = x + dx[d], ny = y + dy[d];
if (grid[x][y] == dir[d])
cost = 0;
else
cost = 1;
}
✍️ 5. Code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int dx[4] = {-1, 1, 0, 0}; // U D L R
const int dy[4] = {0, 0, -1, 1};
const char dir[4] = {'U', 'D', 'L', 'R'};
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--) {
int n,m,k;
cin>>n>>m>>k;
vector<string> v(n);
for(int i=0;i<n;i++)
cin>>v[i];
vector<vector<int> >dist(n,vector<int>(m,INT_MAX));
deque<pair<int,int> >q;
dist[0][0]=0;
//从坐标(0,0)开始搜索
q.emplace_front(0,0);
while(!q.empty()) {
pair<int,int>p = q.front();
int x = p.first;
int y = p.second;
q.pop_front();
for(int i=0;i<4;i++) {
int nx=x+dx[i];
int ny=y+dy[i];
if(nx>=0 && nx<n && ny>=0 && ny<m) {
// 计算从当前格子 (x, y) 走向第 i 个方向的实际代价
int cost=(v[x][y]==dir[i])?0:1;
if(dist[nx][ny]>dist[x][y]+cost) {
dist[nx][ny]=dist[x][y]+cost;
//双端队列核心
if (cost==0)
//放在前面,更优路径,优先处理
q.emplace_front(nx,ny);
else
//放在后面,次优路径,稍后处理
q.emplace_back(nx,ny);
}
}
}
}
if (dist[n-1][m-1]<=k)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
✅ 时间复杂度分析
-
每个点最多访问 1 次(权值0 or 1)
-
总点数 ≤ 1e6,所以 0-1 BFS 的复杂度为 O(n × m),完全可以通过

浙公网安备 33010602011771号