알파벳

[Gold IV] 알파벳 - 1987

문제 링크

성능 요약

메모리: 2020 KB, 시간: 492 ms

분류

백트래킹, 깊이 우선 탐색, 그래프 이론, 그래프 탐색

제출 일자

2024년 7월 10일 15:52:15

문제 설명

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

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

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

입력

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

출력

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


가장 중요한 발상

크기가 작은 Boolean 배열은 그냥 Bit Masking으로 해결

나머지는 일반적인 DFS와 같으므로 설명 생략.

image

#include <iostream>
using namespace std;
int ret;
int R,C;
int visited;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
char**map;
void go(char** map,int x,int y,int depth){
    ret=max(ret,depth);
    visited|=(1<<(map[x][y]-'A'));
    for(int i=0;i<4;i++){
        int nx=x+dx[i];
        int ny=y+dy[i];
        if(nx>=0&&nx<R&&ny>=0&&ny<C){
            if(visited&(1<<(map[nx][ny]-'A'))) continue;
            //visiting process
            go(map,nx,ny,depth+1);
            //restore
            visited^=(1<<(map[nx][ny]-'A'));
        }
    }
}

int main(){

    //init
    cin>>R>>C;
    map=new char*[R];
    for(int i=0;i<R;i++){
        map[i]=new char[C];
    }
    for (int i = 0; i < R; i++) {
        for (int j = 0; j < C; j++) {
            cin >> map[i][j];
        }
    }

    go(map,0,0,1);
   
    cout<<ret<<endl;
    
    return 0;
}

Categories:

Updated:

Leave a comment