130. Blink

题目

描述

在一场DOTA战争中,影魔终于获得获得了传说中的闪烁匕首,也就用了闪烁技能,但是闪烁有个缺陷——我们把地图看做N*N的点阵,假设影魔在点(x,y)上,那么闪烁只能让他到达(x±2,y±2)的四个点,前提是这个点存在并且上面没有石头或者树这种障碍。可恶的是,敌方的英雄早已在地图上布下了减速陷阱,如果踩中陷阱,将会让他减速,但陷阱也会消失!现在影魔要从敌人的包围中逃脱,即从左上顶点(1,1)逃到右下顶点(N,N),请你帮他算出逃脱所需的最短时间!
注:闪烁一次花费1s,踩中陷阱停滞1s,当然,影魔也可以选择向上下左右四个方向移动1个单位,每次移动花费1s。

输入

第一行包含一个数N(2<=N<=50)
接下来的N行表示N*N的地图。其中0表示空地,1表示障碍,2表示陷阱,保证(1,1)和(N,N)为0

输出

输出逃脱花费的最短时间
如果无法逃脱,输出”Impossible”

输入样例
4
0000
0000
0000
0000
输出样例
3

思路分析

BFS,区别在于陷阱需要+1。

【我的代码】

#include 
#include 

typedef struct pos {
    int x, y, cnt;
}pos;

int directions[8][2] = {{2, 2}, {2, -2}, {-2, 2}, {2, -2}, {1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int n;
queue maze;
char map_char;
int map[51][51] = {0};
int visited[51][51] = {0};
int cnt[51][51] = {0};
int min_step = 999999;

int bfs()
{
    int step = 1;
    while (maze.size())
    {
        pos top_item = maze.front();
        maze.pop();
        if (map[top_item.x][top_item.y] == 1 || top_item.x < 1 || top_item.x > n || top_item.y < 1 || top_item.y > n || (visited[top_item.x][top_item.y] == 1 && top_item.cnt >= cnt[top_item.x][top_item.y]))
            continue;
        cnt[top_item.x][top_item.y] = top_item.cnt;
        int tcnt = top_item.cnt + 1;
        if (map[top_item.x][top_item.y] == 2) {
            tcnt++;
        }
        for (int i = 0; i < 8; i++)
        {
            pos new_item = {directions[i][0] + top_item.x, directions[i][1] + top_item.y, tcnt};
            maze.push(new_item);
        }
        visited[top_item.x][top_item.y] = 1;
        step++;
    }
}

int main(){
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            cin >> map_char;
            map[i][j] = int(map_char) - 48;
        }
    }
    pos begin = {1, 1, 0};
    maze.push(begin);
    bfs();
    if (cnt[n][n])
        cout << cnt[n][n] << endl;
    else
        cout << "Impossible" << endl;
    return 0;
}

你可能感兴趣的:(130. Blink)