[c++] BOJ 1600 :: 말이 λ˜κ³ ν”ˆ μ›μˆ­μ΄

λ‚œμ΄λ„ : ?

κ±Έλ¦° μ‹œκ°„ : 1μ‹œκ°„ 반

 

문제

λ™λ¬Όμ›μ—μ„œ 막 νƒˆμΆœν•œ μ›μˆ­μ΄ ν•œ λ§ˆλ¦¬κ°€ 세상ꡬ경을 ν•˜κ³  μžˆλ‹€. κ·Έ 녀석은 말(Horse)이 되기λ₯Ό κ°„μ ˆνžˆ μ›ν–ˆλ‹€. κ·Έλž˜μ„œ κ·ΈλŠ” 말의 μ›€μ§μž„μ„ μœ μ‹¬νžˆ μ‚΄νŽ΄λ³΄κ³  κ·ΈλŒ€λ‘œ 따라 ν•˜κΈ°λ‘œ ν•˜μ˜€λ‹€. 말은 말이닀. 말은 κ²©μžνŒμ—μ„œ 체슀의 λ‚˜μ΄νŠΈμ™€ 같은 이동방식을 가진닀. λ‹€μŒ 그림에 말의 이동방법이 λ‚˜νƒ€λ‚˜μžˆλ‹€. xν‘œμ‹œν•œ 곳으둜 말이 갈 수 μžˆλ‹€λŠ” λœ»μ΄λ‹€. 참고둜 말은 μž₯애물을 λ›°μ–΄λ„˜μ„ 수 μžˆλ‹€.

  x   x  
x       x
    말    
x       x
  x   x  

근데 μ›μˆ­μ΄λŠ” ν•œ 가지 μ°©κ°ν•˜κ³  μžˆλŠ” 것이 μžˆλ‹€. 말은 μ €λ ‡κ²Œ 움직일 수 μžˆμ§€λ§Œ μ›μˆ­μ΄λŠ” λŠ₯λ ₯이 λΆ€μ‘±ν•΄μ„œ 총 K번만 μœ„μ™€ 같이 움직일 수 있고, κ·Έ μ™Έμ—λŠ” κ·Έλƒ₯ μΈμ ‘ν•œ 칸으둜만 움직일 수 μžˆλ‹€. λŒ€κ°μ„  λ°©ν–₯은 μΈμ ‘ν•œ 칸에 ν¬ν•¨λ˜μ§€ μ•ŠλŠ”λ‹€.

이제 μ›μˆ­μ΄λŠ” λ¨Έλ‚˜λ¨Ό 여행길을 λ– λ‚œλ‹€. 격자판의 맨 μ™Όμͺ½ μœ„μ—μ„œ μ‹œμž‘ν•΄μ„œ 맨 였λ₯Έμͺ½ μ•„λž˜κΉŒμ§€ κ°€μ•Όν•œλ‹€. μΈμ ‘ν•œ λ„€ λ°©ν–₯으둜 ν•œ 번 μ›€μ§μ΄λŠ” 것, 말의 μ›€μ§μž„μœΌλ‘œ ν•œ 번 μ›€μ§μ΄λŠ” 것, λͺ¨λ‘ ν•œ 번의 λ™μž‘μœΌλ‘œ μΉœλ‹€. 격자판이 μ£Όμ–΄μ‘Œμ„ λ•Œ, μ›μˆ­μ΄κ°€ μ΅œμ†Œν•œμ˜ λ™μž‘μœΌλ‘œ μ‹œμž‘μ§€μ μ—μ„œ λ„μ°©μ§€μ κΉŒμ§€ 갈 수 μžˆλŠ” 방법을 μ•Œμ•„λ‚΄λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

 

풀이

  • μ΅œλ‹¨ 경둜 λ¬Έμ œμ΄λ―€λ‘œ bfs
  • κ²½λ‘œκ°€ 없을 μˆ˜λ„ 있음 주의

 

μ½”λ“œ

#include <iostream>
#include <queue>

using namespace std;

struct Node {
    int r, c, k, path;
    Node(int row, int col, int num, int p) {
        r = row; c = col; k = num; path = p;
    }
};

int direction[4][2] = { {0,1}, {1,0}, {0, -1}, {-1, 0} };
int horseDirection[8][2] = { {1,2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}, {-2, -1}, {-2, 1}, {-1, 2} };

int map[201][201];
int memo[201][201][31]; // λ©”λͺ¨μ΄μ œμ΄μ…˜ => visited λ°°μ—΄

int main() {
    // 10μ‹œ 10λΆ„ μ‹œμž‘
    // 말의 μ›€μ§μž„μœΌλ‘œ k번, λ‚˜λ¨Έμ§€λŠ” μΈμ ‘ν•œ μΉΈ
    // 0 : 평지, 1: μž₯μ• λ¬Ό
    // kλŠ” 30μ΄ν•˜
    // μ•žμœΌλ‘œ 2 μ˜†μœΌλ‘œ 1
    // bfs (ν•΄λ‹Ή μœ„μΉ˜μ—μ„œ kλ₯Ό μΌλŠ”μ§€ μ•ˆμΌλŠ”μ§€ λ©”λͺ¨μ΄μ œμ΄μ…˜)
    // (r,c,k)

    int K; cin >> K;
    int W, H; cin >> W >> H;

    fill(&map[0][0], &map[200][201], -1);
    fill(&memo[0][0][0], &memo[200][200][30], -1);

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

    int result = 1e8;
    queue<Node*> que;
    que.push(new Node(0, 0, K, 0));
    while (!que.empty()) {
        Node* pos = que.front(); que.pop();
        int path = pos->path + 1; // 넣지 μ•Šκ³  time μ „μ—­λ³€μˆ˜λ‘œ μ‚¬μš©ν•˜λ©΄ 됨
        if (pos->r == H - 1 && pos->c == W - 1) {
            // λ§ˆμ§€λ§‰μ— 도착
            result = result > path - 1 ? path - 1 : result;
            break;
        }


        for (int i = 0; i < 4; i++) {
            int r = pos->r + direction[i][0];
            int c = pos->c + direction[i][1];

            if (r<0 || c<0 || r>=H || c>=W) // 맡 밖에 μœ„μΉ˜
                continue;
            if (map[r][c] == 1) // μž₯애물이 있음
                continue;
            if (memo[r][c][pos->k] != -1) // 이미 듀름 => 사싀 k μ΄ν•˜μ˜ λͺ¨λ“  memoκ°€ 있으면 μ•ˆν•΄λ„ 됨
                continue;
            que.push(new Node(r, c, pos->k, path));
            memo[r][c][pos->k] = 0;
        }

        if (pos->k == 0)
            continue;

        for (int i = 0; i < 8; i++) {
            int r = pos->r + horseDirection[i][0];
            int c = pos->c + horseDirection[i][1];

            if (r < 0 || c < 0 || r >= H || c >= W) // 맡 밖에 μœ„μΉ˜
                continue;
            if (map[r][c] == 1) // μž₯애물이 있음
                continue;
            if (memo[r][c][pos->k-1] != -1) // 이미 듀름 => 넣을 λ•Œ μ²΄ν¬ν•΄μ€˜μ•Ό λ©”λͺ¨λ¦¬ 초과 x
                continue;
            que.push(new Node(r, c, pos->k-1, path)); // K μ‚¬μš©
            memo[r][c][pos->k-1] = 0;
        }
    }
    if (result == 1e8) {
        result = -1;
    }
    cout << result;
}

 

μ£Όμ˜ν•  점

  • bfs μ‹œ time λ³€μˆ˜λ₯Ό μ „μ—­μœΌλ‘œ μ‚¬μš©ν•˜μ—¬ 1μ”© μ¦κ°€μ‹œν‚€λŠ” λ°©μ‹μœΌλ‘œ ν•˜λŠ” 것이 Node struct에 λ„£λŠ” 것보닀 νŽΈν•˜λ‹€.
  • μ΅œμ’… κ²°κ³Όλ₯Ό λ§Œμ‘±ν–ˆμ„ λ•Œμ—λŠ” μ΅œλ‹¨ κ²½λ‘œμ΄λ―€λ‘œ κ·Έλƒ₯ break

 

κ²°κ³Ό

아이디 λ©”λͺ¨λ¦¬ μ‹œκ°„ μ–Έμ–΄ μ½”λ“œ 길이
gmldms784 45488 144 C++17 / μˆ˜μ • 2270
λ°˜μ‘ν˜•