알고리즘/백준(BOJ)

백준 - 1600 말이 되고픈 원숭이

시나모온 2020. 6. 4. 04:54

문제 링크입니다 : https://www.acmicpc.net/problem/1600

 

1600번: 말이 되고픈 원숭이

첫째 줄에 정수 K가 주어진다. 둘째 줄에 격자판의 가로길이 W, 세로길이 H가 주어진다. 그 다음 H줄에 걸쳐 W개의 숫자가 주어지는데, 0은 아무것도 없는 평지, 1은 장애물을 뜻한다. 장애물이 있��

www.acmicpc.net

 

BFS + 점프 문제였습니다.

 

 

 

 

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>

#define INF 987654321

using namespace std;


int K, W, H;

vector<vector<int>> board;
// vector<vector<int>> visited;

int visited[201][201][31];

const int dy[4] = {0, 0, -1, 1};
const int dx[4] = {-1, 1, 0, 0};

const int ndy[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
const int ndx[8] = {1, 2, 2, 1, -1, -2, -2, -1};



int bfs() {
    queue<pair<int, pair<int, pair<int, int>>>> q;

    visited[0][0][K] = 0;
    // max, k, y, x
    q.push({0, {K, {0, 0}}});

    while(!q.empty()) {
        int cmax = -q.front().first;
        int ck = q.front().second.first;
        int cy = q.front().second.second.first;
        int cx = q.front().second.second.second;
        q.pop();



        if(cy == H - 1 && cx == W - 1) {
            return cmax;
        }

        for(int dir = 0; dir < 4; dir++) {
            int ny = cy + dy[dir];
            int nx = cx + dx[dir];

            if(ny < 0 || ny >= H || nx < 0 || nx >= W) continue;
            if(visited[ny][nx][ck] != -1) continue;
            if(board[ny][nx] == 1) continue;
            visited[ny][nx][ck] = cmax + 1;
            q.push({-cmax-1, {ck, {ny, nx}}});
        }

        if(ck > 0) {
            for(int dir = 0; dir < 8; dir++) {
                int ny = cy + ndy[dir];
                int nx = cx + ndx[dir];

                if(ny < 0 || ny >= H || nx < 0 || nx >= W) continue;
                if(visited[ny][nx][ck - 1] != -1) continue;
                if(board[ny][nx] == 1) continue;
                visited[ny][nx][ck - 1] = cmax + 1;
                q.push({-cmax-1, {ck - 1, {ny, nx}}});
            }
        }




    }

    return -1;

}


int main() {
    cin >> K >> W >> H;
    board.assign(H, vector<int>(W));
    // visited.assign(H, vector<int>(W, INF));

    
    memset(visited, -1, sizeof(visited));

    for(int i = 0; i < H; i++) {
        for(int j = 0; j < W; j++) {
            cin >> board[i][j];
        }
    }

    cout << bfs();

    return 0;
}

 

 

 

개발 환경 : vscode

지적, 조언, 질문 환영입니다! 댓글 남겨주세요~