알고리즘/PS - 백준

[백준 1987 - C++] 알파벳 : DFS

excited-hyun 2021. 2. 8. 21:12
반응형

www.acmicpc.net/problem/1987

 

1987번: 알파벳

세로 R칸, 가로 C칸으로 된 표 모양의 보드가 있다. 보드의 각 칸에는 대문자 알파벳이 하나씩 적혀 있고, 좌측 상단 칸 (1행 1열) 에는 말이 놓여 있다. 말은 상하좌우로 인접한 네 칸 중의 한 칸으

www.acmicpc.net

문제

세로 R칸, 가로 C칸으로 된 표 모양의 보드가 있다. 보드의 각 칸에는 대문자 알파벳이 하나씩 적혀 있고, 좌측 상단 칸 (1행 1열) 에는 말이 놓여 있다.

말은 상하좌우로 인접한 네 칸 중의 한 칸으로 이동할 수 있는데, 새로 이동한 칸에 적혀 있는 알파벳은 지금까지 지나온 모든 칸에 적혀 있는 알파벳과는 달라야 한다. 즉, 같은 알파벳이 적힌 칸을 두 번 지날 수 없다.

좌측 상단에서 시작해서, 말이 최대한 몇 칸을 지날 수 있는지를 구하는 프로그램을 작성하시오. 말이 지나는 칸은 좌측 상단의 칸도 포함된다.

 

입력

첫째 줄에 R과 C가 빈칸을 사이에 두고 주어진다. (1 ≤ R,C ≤ 20) 둘째 줄부터 R개의 줄에 걸쳐서 보드에 적혀 있는 C개의 대문자 알파벳들이 빈칸 없이 주어진다.

 

출력

첫째 줄에 말이 지날 수 있는 최대의 칸 수를 출력한다.

 

예제 입력 1 

2 4

CAAB

ADCB

예제 출력 1 

3

 

풀이

이 문제에서는 DFS탐색을 진행하면서 지나온 경로의 알파벳들을 확인해야한다.

따라서 알파벳을 확인할 배열 alpha[26]을 사용하였다. 현재 이어서 지나온 알파벳인 경우 1을, 지나오지 않은 않파벳의 경우 0을 저장한다.

재귀를 통해 DFS를 구현하였으므로 더이상 이동 할 수 있는 정점이 없는 경우엔 재귀호출 종료후 이전 정점으로 돌아온다.

그런데 이때 재귀호출을 종료하기 그 위치가 가진 알파벳을 지난지 여부를 다시 지나지 않은 것으로 수정해 주어야한다!

또한 중복되지 않는 알파벳을 따라 움직이기 때문에 다른 경로로 그 위치를 방문할 수도 있다는 생각이 들어 방문여부를 확인하는 visited배열의 그 위치도 다시 0으로 만들어주었다. (혹시라도 시간초과가 날까봐 걱정했으나 문제없이 실행되었다.)

 

#include <iostream>
#include <cstdio>
#include <vector>

char map[20][20];
int visited[20][20];

int alpha[26];
int X[4] = {1, -1, 0, 0};
int Y[4] = {0, 0, 1, -1};

void dfs(int x, int y, int r, int c);

int cnt, max;

int main(void){
    int r, c;
    scanf("%d %d", &r, &c);
    for(int i=0; i<r; i++){
        scanf("%s", map[i]);
    }
    
    dfs(0, 0, r, c);
    printf("%d\n", max);
}

void dfs(int x, int y, int r, int c){
    int there_x;
    int there_y;
    int ap;
    
    visited[x][y] = 1;
    ap = map[x][y] - 'A';
    alpha[ap] = 1;
    cnt++;
    if(max < cnt)
        max = cnt;
    
    for(int i=0; i<4; i++){
        there_x = x + X[i];
        there_y = y + Y[i];
        if(there_x < 0 || there_x >= r || there_y < 0 || there_y >= c)
            continue;
        ap = map[there_x][there_y] - 'A';
        
        if(visited[there_x][there_y] == 1 || alpha[ap] == 1)
            continue;
        
        dfs(there_x, there_y, r, c);
        
    }
    ap = map[x][y] - 'A';
    alpha[ap] = 0;
    visited[x][y] = 0;
    cnt--;
}
728x90
반응형