Plite
전자오락 공방
Plite
전체 방문자
오늘
어제
  • 분류 전체보기 (274)
    • 프로젝트 (18)
      • 완성 프로젝트 (3)
      • 프로젝트 진행 내역 (15)
    • 공부 및 정리 (241)
      • 백준 코드 (222)
      • C++ (8)
      • DirectX (2)
      • Unreal Engine (6)
      • 프로그래밍 패턴 (3)
    • 기타 (12)
      • 기타 주저리 (10)
    • 게임과 취미 (1)
    • 대문 (1)

블로그 메뉴

  • 홈
  • 프로젝트
  • 취미, 일상
  • 백준 프로필

공지사항

  • [Read Me]
  • 제 블로그에 방문하신 것을 환영합니다.

인기 글

태그

  • 동적계획법
  • 트리
  • 정렬
  • 백준
  • UC++
  • 우선순위큐
  • 구현
  • 투포인터
  • 스택
  • 최소 스패닝 트리
  • 브루트포스
  • 누적합
  • 문자열
  • 위상 정렬
  • SCC
  • C++
  • 기하
  • KMP
  • 조합론
  • 큐
  • 그래프
  • 수학
  • 유니온 파인드
  • LCA
  • 이분탐색
  • 트라이
  • 세그먼트 트리
  • 정수론
  • 백트래킹
  • 분할정복

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Plite

전자오락 공방

[C++]백준 - 1987번 문제
공부 및 정리/백준 코드

[C++]백준 - 1987번 문제

2021. 12. 23. 18:42

1987번: 알파벳 (acmicpc.net)

 

1987번: 알파벳

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

www.acmicpc.net

 

1987번 : 알파벳


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

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

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

 

입력


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

 

 

출력


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

 

 


 

생각해 볼 점


백 트래킹 문제입니다.

 

우선, 그래프 탐색으로 DFS 혹은 BFS를 쓰게 될 것 같은데,

 

DFS가 훨씬 수월할 것입니다.

 

상하좌우로 DFS 탐색을 하되, 여태까지 어떤 알파벳을 밟아왔는지 알아야합니다.

 

따라서, visited라는 배열을 써서

 

26가지 알파벳 중 어떤 알파벳을 밟았는지 체크합니다.

 

백트래킹 문제이므로, DFS에서 돌아올 때는 visited를 다시 원상복구 해야합니다.

 

예시)

 

 

DFS가 C까지 탐색된 경우

 

C의 탐색을 마치고 B부터 다시 DFS를 시작하는 경우

Visited[2] = false;

B에서 E를 향해 DFS를 시작한 경우

 

 

이런 식으로 가장 멀리 간 경우를 구해서 출력하면 될 것 같습니다.

 

코드


#include <iostream>
#include <stack>
using namespace std;

char map[20][21];
int R, C;
int move_x[4] = { 1, 0, -1, 0 };
int move_y[4] = { 0, 1, 0, -1 };

//DFS 탐색
int dfs(pair<int, int> const& current, bool (&visited)[26])
{
	int ret = 1;
	int maxx = 0;
	for (int i = 0; i < 4; i++)
	{
		int new_x = current.first + move_x[i];
		int new_y = current.second + move_y[i];
		if (new_x < 0 || new_y < 0 || C <= new_x || R <= new_y) continue;
		if (visited[map[new_y][new_x] - 'A']) continue;
		visited[map[new_y][new_x] - 'A'] = true;
		int d = dfs({ new_x, new_y }, visited);
		visited[map[new_y][new_x] - 'A'] = false;
		if (maxx < d) maxx = d;
	}
	return ret + maxx;
}

int main()
{
	scanf("%d %d", &R, &C);

	
	for (int i = 0; i < R; i++) scanf("%s", &map[i]);

	bool visited[26] = { 0, };
	visited[map[0][0] - 'A'] = true;
	printf("%d", dfs({ 0,0 }, visited));

	return 0;
}

 

그 외


 

저작자표시

'공부 및 정리 > 백준 코드' 카테고리의 다른 글

[C++]백준 - 11724번 문제  (0) 2021.12.25
[C++]백준 - 1074번 문제  (0) 2021.12.23
[C++]백준 - 2150번 문제  (0) 2021.12.22
[C++]백준 - 11726번 문제  (0) 2021.12.22
[C++]백준 - 13511번 문제  (0) 2021.12.19
    '공부 및 정리/백준 코드' 카테고리의 다른 글
    • [C++]백준 - 11724번 문제
    • [C++]백준 - 1074번 문제
    • [C++]백준 - 2150번 문제
    • [C++]백준 - 11726번 문제
    Plite
    Plite
    개발 일지, 게임 이야기 등을 적어두는 공간입니다.

    티스토리툴바