https://www.acmicpc.net/problem/1987

 

1987번: 알파벳

문제 세로 R칸, 가로 C칸으로 된 표 모양의 보드가 있다. 보드의 각 칸에는 대문자 알파벳이 하나씩 적혀 있고, 좌측 상단 칸 (1행 1열) 에는 말이 놓여 있다. 말은 상하좌우로 인접한 네 칸 중의 한 칸으로 이동할 수 있는데, 새로 이동한 칸에 적혀 있는 알파벳은 지금까지 지나온 모든 칸에 적혀 있는 알파벳과는 달라야 한다. 즉, 같은 알파벳이 적힌 칸을 두 번 지날 수 없다. 좌측 상단에서 시작해서, 말이 최대한 몇 칸을 지날 수 있는지를 구하는

www.acmicpc.net

최근에 공채가 뜨는 기업들이 생겨서 준비를 하느라 블로그에 글을 올릴 여유가 없다보니 소훌해지는 것 같습니다.

블로그를 죽이지 말자는 마음가짐으로 최근에 푼 문제중 쉬운 문제를 리뷰해보려고 합니다.

백준 1987 알파벳입니다.

 

R*C의 2차원 배열이 있고 시작점은 좌측 최상단입니다.

이 때 상,화,좌,우 각 한칸씩 진행할 수 있을 때 밞지 않은 알파벳만을 밞아서 최대한 많이 밞은 횟수를 출력하면 됩니다.

전형적인 DFS를 이용한 백트래킹 문제입니다. 

 

DFS를 돌면서 모든 경우를 해보면 되는데 이 때 백트래킹을 위한 가지치기는 다음 발판이 밞음 이력 유무가 됩니다.

보통 DFS의 경우 방문한 칸을 중복방문하지 않기 위해 이미 밞은 칸을 방문체크합니다.

그러나 이 문제는 (밞았다 == 이미 사용한 알파벳) 이다가 되므로 알파벳 방문 체크만 하고 인덱스 방문 체크는 하지 않아도 됩니다.

 

기본적인 DFS는 기존의 DFS와 같이

(알파벳 방문 체크 ->DFS를 통한 함수 재귀 -> 재귀한 함수 리턴 후 방문 체크 해제)

이런 방식으로 진행하게 됩니다.

 

#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
int R,C,dy[4]={-1,0,1,0},dx[4]={0,1,0,-1},mx=1;
char mat[30][30];
int check[30];

void DFS(int y, int x,int n)
{
    for(int i=0;i<4;i++)
    {
        int ny = y+dy[i], nx=x+dx[i];
        if(ny<0 || nx<0 || ny >= R || nx >= C || check[mat[ny][nx]-'A']) continue;
        mx = max(mx,n+1); check[mat[ny][nx]-'A']=1; if(mx==26) return;
        DFS(ny,nx,n+1);
        check[mat[ny][nx]-'A']=0;
    }
}
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    cin >> R >> C;
    for(int i=0;i<R;i++)
    {
        for(int j=0;j<C;j++)
        {
            cin >> mat[i][j];
        }
    }
    check[mat[0][0]-'A']=1;
    DFS(0,0,1);
    cout << mx;


}

 매우 간단한 문제입니다.

solved.ac 기준으로 골드3이 측정되어있지만 더 낮은 난이도를 부여해도 될 것 같습니다.

'알고리즘 > PS' 카테고리의 다른 글

[백준 20167] 꿈틀꿈틀 호석 애벌레 - 기능성  (0) 2020.12.29
[백준 1360] 되돌리기  (0) 2020.06.05
[백준 12865] 평범한 배낭  (2) 2020.03.26
[백준 12100] 2048(Easy)  (0) 2020.03.25
[백준 11062] 카드 게임  (0) 2020.03.12

+ Recent posts