본문 바로가기
Algorithm/문제풀이

[백준] 알파벳

by GraceIT 2019. 9. 5.

■ 문제

세로 R칸, 가로 C칸으로 된 표 모양의 보드가 있다. 보드의 각 칸에는 대문자 알파벳이 하나씩 적혀 있고,

좌측 상단 칸 (1행 1열) 에는 말이 놓여 있다.

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

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

 

■ 입력

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

 

■ 출력

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

 

■ 예제

입력  출력 
2 4
CAAB
ADCB
3

 

▶ 코드

 

지날 수 있는 모든 경우의 수(DFS) 중에 가장 큰 경우를 출력하는 것이다.

 

dfs 함수 안을 살펴보자

 

1. 방문한 곳인지 아닌지는 visited배열로 확인하고 이미 지난 알파벳인지 아닌지는 alphabet배열로 확인하며,

이미 지난 곳이거나 지난 알파벳이라면 return 한다.

if(alphabet[alpha] || visited[x][y]) return;

2.그렇지 않다면 방문하지 않은 경우이므로 visited와 alphabet을 true로 바꾼다.

alphabet[alpha] = true;
visited[x][y] = true;
count++;

3. 만약 최종 출력 값인 passed보다 count가 크다면 passed를 수정한다.

if(count>passed) passed= count;

4. 상하좌우를 돌며 갈 수 있는 곳이라면 재귀로 dfs를 호출한다.

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){
		dfs(nx,ny,count);
	}	
}

5. 주의할 점은 dfs가 종료 될 때, visited와 alphabet을 false로 풀어주어 다른 경우에서도 방문 할 수 있게 해야한다.

alphabet[alpha] = false;
visited[x][y] = false;

전체 코드는 아래와 같다.

#include <iostream>
#include <vector>

using namespace std;

int r, c ;
char map[21][21];
bool visited[21][21]={false};
bool alphabet[26]={false};
int passed =0;
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};

void dfs(int x, int y, int count){
	
	int alpha = map[x][y] - 65;
	
	if(alphabet[alpha] || visited[x][y]) return;
	
	alphabet[alpha] = true;
	visited[x][y] = true;
	count++;
	
	if(count>passed) passed= count;
	
	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){
			dfs(nx,ny,count);
		}	
	}
	
	alphabet[alpha] = false;
	visited[x][y] = false;
	
}

int main(){
	
	
	//input
	cin >> r >> c;
	 
	for(int i=0;i<r;i++)
		for(int j=0;j<c;j++)
			cin >> map[i][j];
			
	dfs(0,0,0); //dfs( x좌표, y좌표, 지난 칸의 수)
	
	cout << passed;
	
	return 0;
} 

 

 

※ 출처 : https://www.acmicpc.net/problem/1987

 

1987번: 알파벳

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

www.acmicpc.net

 

'Algorithm > 문제풀이' 카테고리의 다른 글

[백준] 로또  (0) 2019.09.06
[백준] 분해합  (0) 2019.09.04
[프로그래머스] 가장 큰 수  (0) 2019.09.04
[프로그래머스] 주식 가격  (0) 2019.08.30
[백준] 거북이  (0) 2019.08.30

댓글