逃出克隆岛 (codevs 2059)

较普通的走迷宫的题

传送门 :codevs 2059 逃出克隆岛

思路 :BFS 即可    PS :传送门 不必重复使用 

#include <iostream>
#include <cstdio>
#define Max 2020
using namespace std;
int N, M;
int start_x, start_y, end_x, end_y;
int move_x [5] = {1, -1, 0, 0}, move_y [5] = {0, 0, 1, -1};
char map [Max][Max];
int queue [Max][3];
int cost [Max * 10];
bool door [Max][Max], visit [Max][Max];
bool flag; 
int pay;
void BFS (int start_x, int start_y)
{
    int head_cur = 0, tail_cur = 1;
    visit [start_x][start_y] = true;  //标记当前点为 已访问 
    queue [1][1] = start_x; //将起点入队列 
    queue [1][2] = start_y;
    cost [1] = 0;  // 当前的花费为0 
    while (head_cur < tail_cur)
    {
        head_cur++;
        for (int i = 0; i <= 3; i++)
        {
            int x = queue [head_cur][1] + move_x [i];
            int y = queue [head_cur][2] + move_y [i];
            if (x == end_x && y == end_y)  // 如果到达了终点, flag 标记为 true 直接输出花费即可 
            {
                flag = true;
                cout << cost [head_cur];
                return;
            }
            if (x > 0 && x <= N && y > 0 && y <= M && map [x][y] != '#' && visit [x][y] == false) // 在边界内,且当前点 不是障碍点 且当前点未访问 
            {
                if (door [x][y] == true)  //如果此点为传送门,且当前传送门可以走 
                {
                    door [x][y] = false;  // 标记为已走 
                    for (int i = 1; i <= N; i++)  
                        for (int j = 1; j <= M; j++)  //在全图内搜索 可走的传送门 
                            if (door [i][j] == true)
                            {
                                tail_cur++;
                                queue [tail_cur][1] = i; //将当前传送到的位置加入队列 
                                queue [tail_cur][2] = j; 
                                door [i][j] = false;  // 标记此传送门为已走 
                                cost [tail_cur] = cost [head_cur];  //由于传送门没有花费, 所以等于前一个点的花费 
                            }
                }
                tail_cur++;  // 如果不是传送门 ,将当前位置加入队列 
                queue [tail_cur][1] = x;
                queue [tail_cur][2] = y;
                visit [x][y] = true;  // 标记为已访问 
                if (map [x][y] == '*') //如果走此点需要花费 
                    cost [tail_cur] = cost [head_cur] + pay;  // 上一个点的花费 再加一次花费 即为当前位置的花费 
                else 
                    cost [tail_cur] = cost [head_cur];  // 若是普通点,则当前点的花费等于上一个点的花费 
            }
        }
    }
}
int main()
{
    ios :: sync_with_stdio (false);
    cin >> N >> M >> pay;  
    for (int i = 1; i <= N; i++)
        for (int j = 1; j <= M; j++)
        {
            cin >> map [i][j];
            if (map [i][j] == 'Y')  // 记录起点 
            {
                start_x = i;
                start_y = j;
            }
            else if (map [i][j] == 'C')  //记录终点 
            {
                end_x = i;
                end_y = j;
            }
            else if (map [i][j] == 'P')  //记录传送门的位置 标记当前传送门可访问 
                door [i][j] = true;
        }
    BFS (start_x, start_y); 
    if (flag == false)    // 若走不通  
        cout << "screw you!";
    return 0;
}
原文地址:https://www.cnblogs.com/ZlycerQan/p/6066279.html