[ABC176D] Wizard in Maze

KukCair發表於2024-11-23

誰沒事手擼魔法方向陣列啊

正解:

題目上說最少使用幾次魔法,因此一定是正常上下左右移動的優先順序更高。

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;
}

相關文章