알파벳

[Gold IV] 알파벳 - 1987

문제 링크

성능 요약

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

분류

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

제출 일자

2024년 7월 10일 15:52:15

문제 설명

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

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

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

입력

첫째 줄에 RC가 빈칸을 사이에 두고 주어진다. (1R,C20) 둘째 줄부터 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