Algorithm 문제/BOJ

[c++] BOJ 1987 :: μ•ŒνŒŒλ²³

희은w 2021. 4. 28. 21:31

λ‚œμ΄λ„ : κ³¨λ“œ 4

κ±Έλ¦° μ‹œκ°„ : 40λΆ„

 

문제

μ•ŒνŒŒλ²³ 문제 λ°”λ‘œκ°€κΈ°

μ‹œκ°„ μ œν•œ λ©”λͺ¨λ¦¬ μ œν•œ 제좜 μ •λ‹΅ λ§žμ€ μ‚¬λžŒ μ •λ‹΅ λΉ„μœ¨
2 초 256 MB 49866 15734 9600 29.155%

μ„Έλ‘œ RμΉΈ, κ°€λ‘œ C칸으둜 된 ν‘œ λͺ¨μ–‘μ˜ λ³΄λ“œκ°€ μžˆλ‹€. λ³΄λ“œμ˜ 각 μΉΈμ—λŠ” λŒ€λ¬Έμž μ•ŒνŒŒλ²³μ΄ ν•˜λ‚˜μ”© μ ν˜€ 있고, 쒌츑 상단 μΉΈ (1ν–‰ 1μ—΄) μ—λŠ” 말이 놓여 μžˆλ‹€.

말은 μƒν•˜μ’Œμš°λ‘œ μΈμ ‘ν•œ λ„€ μΉΈ μ€‘μ˜ ν•œ 칸으둜 이동할 수 μžˆλŠ”λ°, μƒˆλ‘œ μ΄λ™ν•œ 칸에 μ ν˜€ μžˆλŠ” μ•ŒνŒŒλ²³μ€ μ§€κΈˆκΉŒμ§€ μ§€λ‚˜μ˜¨ λͺ¨λ“  칸에 μ ν˜€ μžˆλŠ” μ•ŒνŒŒλ²³κ³ΌλŠ” 달라야 ν•œλ‹€. 즉, 같은 μ•ŒνŒŒλ²³μ΄ 적힌 칸을 두 번 μ§€λ‚  수 μ—†λ‹€.

쒌츑 μƒλ‹¨μ—μ„œ μ‹œμž‘ν•΄μ„œ, 말이 μ΅œλŒ€ν•œ λͺ‡ 칸을 μ§€λ‚  수 μžˆλŠ”μ§€λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€. 말이 μ§€λ‚˜λŠ” 칸은 쒌츑 μƒλ‹¨μ˜ 칸도 ν¬ν•¨λœλ‹€.

 

풀이

  • 주의! μž…λ ₯이 20μ΄λ―€λ‘œ μ μ§€λ§Œ 경둜 λ¬Έμ œμ΄λ―€λ‘œ κΈΈμ–΄μ§ˆ 수 있음
  • DFSλ₯Ό μ‚¬μš©
  • μ§€κΈˆκΉŒμ§€ λ‚˜μ˜¨ μ•ŒνŒŒλ²³μ„ μ €μž₯ν•˜λŠ” 방법
    • unordered_set
    • int λ°°μ—΄

 

μ½”λ“œ

#include <iostream>
#include <queue>

using namespace std;

int direction[4][2] = { {0,1}, {1,0}, {0, -1}, {-1, 0} };
int R, C;
char arr[21][21];
int visited[26];
int res = -1;

void dfs(int r, int c, int num) {
    res = res < num ? num : res;

    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 >= R || cp >= C) // λ§΅ 밖에 μœ„μΉ˜ν•˜λ©΄ μ œμ™Έ
            continue;
        if (!visited[arr[rp][cp]-'A']) {
            // κ²½λ‘œμ— 이미 ν¬ν•¨λ˜μ–΄ μžˆλŠ” 곳은 μ œμ™Έ
            visited[arr[rp][cp] - 'A'] = 1;
            num++;
            dfs(rp, cp, num);
            num--;
            visited[arr[rp][cp] - 'A'] = 0;
        }
    }
}

int main() {
    // μž…λ ₯ λ°›κΈ°
    cin >> R >> C;
    for (int i = 0; i < R; i++) {
        for (int j = 0; j < C; j++) {
            cin >> arr[i][j];
        }
    }

    fill(&visited[0], &visited[25], 0); // μ΄ˆκΈ°ν™”
    visited[arr[0][0]-'A'] = 1;
    dfs(0, 0, 1);
    cout << res << '\n';
}

 

μ£Όμ˜ν•  점

  • λ©”λͺ¨μ΄μ œμ΄μ…˜μ„ μ‚¬μš©ν•΄λ³΄λ €κ³  ν–ˆμ§€λ§Œ ν•΄λ‹Ή μœ„μΉ˜μ—μ„œμ˜ κ°€λŠ₯ μ΅œλŒ€ κ²½λ‘œκ°€ 이전 κ²½λ‘œμ— μ’…μ†μ μ΄λ―€λ‘œ (ν•΄λ‹Ή μœ„μΉ˜κΉŒμ§€μ˜ κ²½λ‘œκ°€ 달라지면 μ•žμœΌλ‘œ κ°€λŠ₯ν•œ κ²½λ‘œλ„ λ‹¬λΌμ§€λ―€λ‘œ) λΆˆκ°€λŠ₯
  • unordered_set으둜 μ €μž₯해보렀고 ν–ˆμ§€λ§Œ μ‹œκ°„μ΄ˆκ³Όκ°€ λ‚˜μ˜΄ => κΈ°λ³Έ λ°°μ—΄λ‘œ ν•˜λŠ” 것이 μ’‹μŒ
    • unordered_set의 μ‚½μž… μ‹œκ°„ λ³΅μž‘λ„ O(N)와 find μ‹œκ°„ λ³΅μž‘λ„ O(N)을 κ°€μ§€κ³  있기 λ•Œλ¬Έμ΄λ‹€.
    • λ°°μ—΄λ‘œ ν•˜λ©΄ ν•΄λ‹Ή μ•ŒνŒŒλ²³μ΄ 이미 λ‚˜μ™”λŠ”μ§€ ν™•μΈν•˜κΈ° μœ„ν•΄ O(1)의 μ‹œκ°„λ³΅μž‘λ„κ°€ ν•„μš”ν•˜λ‹€.

 

κ²°κ³Ό

λ°˜μ‘ν˜•