谁没事手撸魔法方向数组啊
正解:
题目上说最少使用几次魔法,因此一定是正常上下左右移动的优先级更高。
bfs 的特点就是会先算队首,这也就意味着队首的优先级更高。
从队首入队,需要使用 deque
。此题中的 step
数组用于记录到当前点用了多少次魔法。
#include <bits/stdc++.h>
using namespace std;
struct p{
int x, y;
};
int h, w, a, b, x, y, step[1005][1005];
//正常上下左右移动
int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
//魔法方向数组
int sy[] = {-2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2};
int sx[] = {-2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2};
void bfs(){
deque<p> q;//双端队列
q.push_back({a, b});//初始起点入队
step[a][b] = 0;//初始时最少使用0次魔法
while(!q.empty()){
int mx = q.front().x, my = q.front().y;
q.pop_front();
for(int i = 0; i <= 3; i++){//上下左右移动的
int nx = mx + dx[i], ny = my + dy[i];
//越界
if(nx > h || ny > w || nx < 1 || ny < 1)continue;
//一个点可以重复走过,但如果新的次数还大于原来的就不用往下找了,一定不会是最优解
if(m[nx][ny] == '#' || step[nx][ny] <= step[mx][my])continue;
step[nx][ny] = step[mx][my];
q.push_front({nx, ny});//正常的优先级高,放前面
}
for(int i = 0; i <= 23; i++){//使用魔法的
int nx = mx + sx[i], ny = my + sy[i];
if(nx > h || ny > w || nx < 1 || ny < 1)continue;
if(m[nx][ny] == '#' || step[nx][ny] <= step[mx][my] + 1)continue;
step[nx][ny] = step[mx][my] + 1;
q.push_back({nx, ny});//使用魔法的的优先级低,放后面
}
}
if(step[x][y] != 0x3f3f3f3f) cout << step[x][y];//能走到
else cout << -1;
}
int main(){
memset(step, 0x3f, sizeof(step));//初始化,以免在取最小值时全为0
cin >> h >> w >> a >> b >> x >> y;
for(int i = 1; i <= h; i++)
for(int j = 1; j <= w; j++)
cin >> m[i][j];
bfs();
return 0;
}
标签:bfs,魔法,int,Wizard,ABC176D,nx,ny,step,Maze
From: https://www.cnblogs.com/KukCair/p/18564694