[c++] BOJ 2206 :: ๋ฒฝ ๋ถ€์ˆ˜๊ณ  ์ด๋™ํ•˜๊ธฐ

๋‚œ์ด๋„ : ๊ณจ๋“œ 4

๊ฑธ๋ฆฐ ์‹œ๊ฐ„ : ์˜ค๋ž˜ ๊ฑธ๋ฆผ

๋ฌธ์ œ

๋ฒฝ ๋ถ€์ˆ˜๊ณ  ์ด๋™ํ•˜๊ธฐ ๋ฌธ์ œ ๋ณด๋Ÿฌ๊ฐ€๊ธฐ

Nร—M์˜ ํ–‰๋ ฌ๋กœ ํ‘œํ˜„๋˜๋Š” ๋งต์ด ์žˆ๋‹ค. ๋งต์—์„œ 0์€ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋Š” ๊ณณ์„ ๋‚˜ํƒ€๋‚ด๊ณ , 1์€ ์ด๋™ํ•  ์ˆ˜ ์—†๋Š” ๋ฒฝ์ด ์žˆ๋Š” ๊ณณ์„ ๋‚˜ํƒ€๋‚ธ๋‹ค. ๋‹น์‹ ์€ (1, 1)์—์„œ (N, M)์˜ ์œ„์น˜๊นŒ์ง€ ์ด๋™ํ•˜๋ ค ํ•˜๋Š”๋ฐ, ์ด๋•Œ ์ตœ๋‹จ ๊ฒฝ๋กœ๋กœ ์ด๋™ํ•˜๋ ค ํ•œ๋‹ค. ์ตœ๋‹จ๊ฒฝ๋กœ๋Š” ๋งต์—์„œ ๊ฐ€์žฅ ์ ์€ ๊ฐœ์ˆ˜์˜ ์นธ์„ ์ง€๋‚˜๋Š” ๊ฒฝ๋กœ๋ฅผ ๋งํ•˜๋Š”๋ฐ, ์ด๋•Œ ์‹œ์ž‘ํ•˜๋Š” ์นธ๊ณผ ๋๋‚˜๋Š” ์นธ๋„ ํฌํ•จํ•ด์„œ ์„ผ๋‹ค.

๋งŒ์•ฝ์— ์ด๋™ํ•˜๋Š” ๋„์ค‘์— ํ•œ ๊ฐœ์˜ ๋ฒฝ์„ ๋ถ€์ˆ˜๊ณ  ์ด๋™ํ•˜๋Š” ๊ฒƒ์ด ์ข€ ๋” ๊ฒฝ๋กœ๊ฐ€ ์งง์•„์ง„๋‹ค๋ฉด, ๋ฒฝ์„ ํ•œ ๊ฐœ ๊นŒ์ง€ ๋ถ€์ˆ˜๊ณ  ์ด๋™ํ•˜์—ฌ๋„ ๋œ๋‹ค.

ํ•œ ์นธ์—์„œ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋Š” ์นธ์€ ์ƒํ•˜์ขŒ์šฐ๋กœ ์ธ์ ‘ํ•œ ์นธ์ด๋‹ค.

๋งต์ด ์ฃผ์–ด์กŒ์„ ๋•Œ, ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•ด ๋‚ด๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค.

 

ํ’€์ด

  • ๋ชจ๋“  ๊ฒฝ๋กœ๋ฅผ ์‚ดํŽด๋ณผ ํ•„์š”์—†์ด ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•˜๋ฉด ๋˜๋ฏ€๋กœ bfs๋ฅผ ์ด์šฉํ•œ๋‹ค.
  • ๋ฒฝ์„ ๋ถ€์ˆ˜๊ณ  ์ด๋™ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ฒฝ์„ ๋ถ€์‰ˆ๋Š”์ง€์˜ ์—ฌ๋ถ€๊นŒ์ง€ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•ด์•ผํ•œ๋‹ค.

 

์ฝ”๋“œ

[dfs] => ํ‹€๋ฆฐ ์ฝ”๋“œ

#include <iostream>
#include <string>
#include <cstring>

using namespace std;

int N, M;
int map[1001][1001];
int direction[4][2] = { {0,1},{-1,0},{0,-1},{1,0} };
int memo[1001][1001][2];

int shortestPath(bool brakeRemain, int r, int c) {
    if (r == N - 1 && c == M - 1)
        return 1;
    int minPath = 1e8;
    for (int i = 0; i < 4; i++) {
        int rp = r + direction[i][0];
        int cp = c + direction[i][1];
        int type = 0;

        if (rp < 0 || cp < 0 || rp >= N || cp >= M) // ๋งต ์•ˆ์— ์—†์œผ๋ฉด
            continue;
        if (brakeRemain)
            type = 1;

        int res;
        if (map[rp][cp] == 0) {
            if (memo[rp][cp][type] != -1)
                res = memo[rp][cp][type];
            else {
                memo[rp][cp][type] = 1e8;
                res = shortestPath(brakeRemain, rp, cp) + 1;
                memo[rp][cp][type] = res;
            }
            if (minPath > res)
                minPath = res;
        }
        else {
            // ๋ฒฝ์ด๋ฉด
            if (!brakeRemain) // ๋ถ€์ˆ  ์ˆ˜ ์—†์œผ๋ฉด ๊ฑด๋„ˆ๋›ฐ๊ธฐ
                continue;
            if (memo[rp][cp][0] != -1) // ๋ฉ”๋ชจ์ด์ œ์ด์…˜
                res = memo[rp][cp][0];
            else {
                memo[rp][cp][0] = 1e8; // ๋‹ค์‹œ ๋˜๋Œ์•„์˜ค์ง€ ๋ชปํ•˜๊ฒŒ
                res = shortestPath(!brakeRemain, rp, cp) + 1;
                memo[rp][cp][0] = res;
            }
            if (minPath > res)
                minPath = res;
        }
    }

    return minPath;
}

int main() {
    cin >> N >> M;
    for (int i = 0; i < N; i++) {
        string str;
        cin >> str;
        for (int j = 0; j < str.size(); j++) {
            map[i][j] = str[j]-'0';
        }
    }
    memset(memo, -1, sizeof(memo));

    int res = shortestPath(true, 0, 0);
    if (res >= 1e8)
        res = -1;
    cout << res;

}

[bfs] => ์„ฑ๊ณต ์ฝ”๋“œ

#include <iostream>
#include <string>
#include <cstring>
#include <queue>

using namespace std;

int N, M;
int map[1001][1001];
int direction[4][2] = { {0,1},{-1,0},{0,-1},{1,0} };
int memo[1001][1001][2];

struct Node {
    int r;
    int c;
    bool breakRemain = true;
    int p;
    Node(int row, int col, bool b) {
        r = row; c = col; breakRemain = b; p = 0;
    }
    Node(int row, int col, bool b, int path) {
        r = row; c = col; breakRemain= b; p = path;
    }
};

int main() {
    // 11์‹œ 40๋ถ„ ์‹œ์ž‘
    // ๋ฒฝ ํ•˜๋‚˜๋Š” ๋ถ€์ˆด๋„ ๋จ
    // ์ƒํ•˜์ขŒ์šฐ ์ด๋™
    // ์ตœ๋‹จ ๊ฒฝ๋กœ
    // n,m ์€ 1000์ดํ•˜
    // ๋ถˆ๊ฐ€๋Šฅ ์‹œ -1
    // ์ž‘์€ ๋ฌธ์ œ : ํ•ด๋‹น ์นธ์—์„œ ๋งˆ์ง€๋ง‰๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ
    // ์ž…๋ ฅ : ์ง€๊ธˆ๊นŒ์ง€ ๋ฒฝ์„ ๋ถ€์ˆœ์ ์ด ์žˆ๋Š”์ง€, ํ˜„์žฌ ์นธ
    // ์ถœ๋ ฅ : ์ตœ๋‹จ ๊ฒฝ๋กœ
    // ๋ฉ”๋ชจ์ด์ œ์ด์…˜ : ํ•ด๋‹น ์นธ, ๋ฒฝ ๋ถ€์ˆจ ์—ฌ๋ถ€
    // ์ข…๋ฃŒ : ๋งˆ์ง€๋ง‰ ์นธ์— ๋„๋‹ฌ, ๋” ๊ฐˆ๊ณณ์ด ์—†๊ณ  ๋ฒฝ๋ถ€์ˆจ๋„ ์—†์Œ

    cin >> N >> M;
    for (int i = 0; i < N; i++) {
        string str;
        cin >> str;
        for (int j = 0; j < str.size(); j++) {
            map[i][j] = str[j]-'0';
        }
    }
    memset(memo, -1, sizeof(memo));

    queue<Node*> que;
    que.push(new Node(0, 0, true));
    memo[0][0][0] = 0;
    memo[0][0][1] = 0;

    int flag = 1;
    while (!que.empty()) {
        Node* node = que.front(); que.pop();
        int r = node->r; int c = node->c; bool b = node->breakRemain;
        int path = node->p +1;
        if (r == N - 1 && c == M - 1) {
            // ๋งˆ์ง€๋ง‰ ๋„์ฐฉ
            flag = 0;
            cout << path;
            break;
        }
        for (int i = 0; i < 4; i++) {
            int rp = r + direction[i][0];
            int cp = c + direction[i][1];
            if (rp < 0 || cp < 0 || rp >= N || cp >= M) // ๋งต ์•ˆ์— ์—†์œผ๋ฉด
                continue;
            if (memo[rp][cp][b ? 1 : 0] != -1) // ์ด๋ฏธ ํ–ˆ๋˜ ๊ณณ์ด๋ฉด
                continue;

            if (map[rp][cp] == 0) {
                // ๋ฒฝ์ด ์•„๋‹ˆ๋ฉด
                que.push(new Node(rp, cp, b, path));
                memo[rp][cp][b ? 1 : 0] = path;
            }
            else {
                // ๋ฒฝ์ด๋ฉด
                if (!b) // ๋ฒฝ๋ถ€์ˆ˜๊ธฐ๊ฐ€ ์—†์œผ๋ฉด
                    continue;
                que.push(new Node(rp, cp, false, path));
                memo[rp][cp][b ? 1 : 0] = path;
            }
        }
    }
    if (flag) {
        cout << -1;
    }
}

 

๊ฒฐ๊ณผ

๋ฐ˜์‘ํ˜•