201604-4(遊戲)

/*ccf 201604_4
    
    普通的bfs,但是注意當無路可走的時候是可以回到上一次走過的格子的,所以不能用普通的
    標記像vis[i][j]來表示某個格子曾走過。應該採用拆點的思想,vis[i][j][t]表示t時刻走過
    格子i,j。其餘按照套路走即可。
*/
#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>

using namespace std;
const int maxn = 105;
const int dx[] = {0, 0, 1, -1};
const int dy[] = {1, -1, 0, 0};

int board[maxn][maxn], s[maxn][maxn], e[maxn][maxn];
int n, m, t;
bool vis[maxn][maxn][maxn];

struct Node
{
    int row, col, time;
    Node(int r, int c, int t):row(r), col(c), time(t) {}
    Node(){}
};

inline bool inside(int x, int y)
{
    return x >= 0 && x < n && y >= 0 && y < m;
}

inline bool safe(int x, int y, int t)
{
    return t < s[x][y] || t > e[x][y];
}

int bfs()
{
    queue<Node> q;
    q.push(Node(0, 0, 0));

    while(!q.empty()) {
        Node x = q.front(); q.pop();
        //printf("#%d %d = %d\n", x.row, x.col, x.time);
        if(x.row == n-1 && x.col == m-1) return x.time;

        if(vis[x.row][x.col][x.time])   continue;
        vis[x.row][x.col][x.time] = true;

        for(int d = 0; d < 4; d++) {
            int nx = x.row + dx[d];
            int ny = x.col + dy[d];
            if(inside(nx, ny) && safe(nx, ny, x.time + 1) && !vis[nx][ny][x.time+1]) {
                q.push(Node(nx, ny, x.time + 1));
            }
        }
    }
}

int main()
{
    //freopen("in.txt", "r", stdin);
    memset(board, 0, sizeof(board));
    memset(s, 0, sizeof(s));    memset(e, 0, sizeof(e));
    memset(vis, 0, sizeof(vis));

    scanf("%d%d%d", &n, &m, &t);

    int r, c, a, b;
    for(int i = 0; i < t; i++) {
        scanf("%d%d%d%d", &r, &c, &a, &b);
        r--;    c--;
        s[r][c] = a;    e[r][c] = b;
    }
    printf("%d\n", bfs());
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章