이것저것

BOJ - 1987. 알파벳 본문

Problem Solving

BOJ - 1987. 알파벳

nays111 2021. 1. 19. 10:42

문제

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

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

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

입력

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

출력

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

예제 입력 1

2 4
CAAB
ADCB

예제 출력 1

3


풀이 과정

  • 문제에서는 대문자 알파벳들이 빈칸없이 주어진다 하여서 문자를 숫자로 바꾸어 이차원 배열에 저장해두었습니다.
  • DFS를 사용하였는데, void dfs(int y,int x,int index) 에서의 index는 현재 좌표에 오기까지 몇 칸을 왔는지를 나타냅니다.
  • 문제에서 말이 지날 수 있는 최대의 칸수를 구하라고 하므로 반복하는 재귀 중 가장 큰 index를 선택해주면 됩니다.
void dfs(int y,int x,int index){
    visit[arr[y][x]]=true;
    answer = max(answer,index);
  • 상하좌우로 검사하면서 방문하지 않은 곳에 대해 DFS 탐색을 진행하면 됩니다.
  • 알파벳을 중복해서는 탐색할 수 없으므로, 방문 배열에 숫자로 치환한 알파벳들을 넣어주면 됩니다.
  • 한 번 탐색하기 시작할 때, 방문을 체크하는데 더 이상 탐색할 곳이 없어서 backtraking 할 때는 꼭 방문 체크를 다시 없애줘야합니다.

(최대 몇 칸을 움직일 수 있는지를 구해야하므로, 다른 방향으로 또 탐색을 진행하여 뭐가 더 큰지를 알아내야하기 때문입니다.)


전체 소스 코드

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <functional>
using namespace std;

int arr[27][27];
bool visit[27];
int r,c;
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int answer = 0;

void dfs(int y,int x,int index){
    visit[arr[y][x]]=true;
    //cout<<index<<'\n';
    answer = max(answer,index);
    for(int i=0;i<4;i++){
        int nextY = y+dy[i];
        int nextX = x+dx[i];
        if(nextY<0 || nextX<0 || nextY>=r || nextX>=c){
            continue;
        }

        if(visit[arr[nextY][nextX]]==false){
            //cout<<nextY<<" "<<nextX<<'\n';
            dfs(nextY,nextX,index+1);
        }
    }
    visit[arr[y][x]]=false;
}

int main(){
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(false);
    cin>>r>>c;
    for(int i=0;i<r;i++){
        string str;
        cin>>str;
        for(int j=0;j<c;j++){
            arr[i][j]=str[j]-'A';
        }
    }

    dfs(0,0,1);
    cout<<answer;
    return 0;

}

'Problem Solving' 카테고리의 다른 글

BOJ - 1743. 음식물 피하기  (0) 2021.01.19
BOJ - 10026. 적록색약  (0) 2021.01.19
BOJ - 11724. 연결 요소의 개수  (0) 2021.01.19
BOJ - 6593. 상범 빌딩  (0) 2021.01.19
BOJ - 2178. 미로 탐색  (0) 2021.01.18
Comments