1987번 - 알파벳
2024-01-31
#C++#백준
문제 풀이 시간 : 1시간
문제 요약
- •
보드의 각 칸에는 알파벳이 있음
- •
주변의 네 칸 중 다른 칸으로 이동한다.
- •
새로 이동한 칸은 지금까지 지나온 알파벳이 아니어야 함.
- •
최대로 갈 수 있는 칸 수 구하기
문제 풀이
이 문제는 간단하게 DFS로 풀 수 있겠다고 생각했다.
초기 코드
#include <iostream>
#include <vector>
#include <string>
using namespace std;
char board[21][21];
int arr[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
int r, c, ans;
bool check(int x, int y) { //보드를 넘어가는지 확인
if ((x >= 0 && x < r) && (y >= 0 && y < c))
return true;
else
return false;
}
void find(bool visited[21], int x, int y, int sum) { //DFS함수
int tx, ty;
ans = max(sum, ans); //현재 값이 최댓값보다 크면 교체
visited[board[x][y] - 'A'] = true; //방문 처리
for (int i = 0; i < 4; i++) { //주변 칸 탐색
tx = x + arr[i][0];
ty = y + arr[i][1];
if (check(tx, ty)) { //보드를 넘어가지 않으면
if (!visited[board[tx][ty] - 'A']) { //방문되지 않았다면
find(visited, tx, ty, sum + 1);
}
}
}
}
int main() {
string input;
cin >> r >> c;
for (int i = 0; i < r; i++) {
cin >> input;
for (int j = 0; j < c; j++)
board[i][j] = input[j];
}
bool visited[21] = {false};
visited[board[0][0] - 'A'] = true;
find(visited, 0, 0, 1);
cout << ans;
}
위 코드는 아쉽게도 바로 틀렸다고 한다.
이유가 무엇일까?
이유는 이미 방문 했더라도 다른 경우가 있을 수 있기 때문에 방문 후 다시 방문하지 않았다고 해주어야 한다.
아래와 같은 경우를 보자.
(0,0)에서 시작하므로 갈 수 있는 칸은 (1,0)과 (0,1)이다.
이때 만약 (1,0)으로 간다면 (2,0)과 (1,1) 모두 이미 방문한 것이므로 이동 횟수는 2이다.
하지만 (0,0)에서 (0,1)로 이동한다면 아래와 같이 4가 나온다.
따라서 다른 칸으로 방문한 후 visited를 다시 false로 바꿔주어 주변의 다른 칸에 같은 알파벳이 있어도 방문할 수 있도록 해주어야한다.
최종 코드
#include <iostream>
#include <algorithm>
using namespace std;
char board[21][21];
int arr[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
int r, c, ans;
bool check(int x, int y) { //보드를 넘어가는지 확인
if (x >= 0 && x < r && y >= 0 && y < c)
return true;
else
return false;
}
void find(bool visited[27], int x, int y, int sum) { //DFS함수
int tx, ty;
if (ans < sum) //현재값이 최댓값보다 크면 교체
ans = sum;
for (int i = 0; i < 4; i++) { //주변 칸 탐색
tx = x + arr[i][0];
ty = y + arr[i][1];
if (check(tx, ty)) { //보드를 넘어가지 않고
if (!visited[board[tx][ty] - 'A']) { //방문하지 않았다면
visited[board[tx][ty] - 'A'] = true; //방문 처리
find(visited, tx, ty, sum + 1); //DFS 호출
visited[board[tx][ty] - 'A'] = false; //방문 취소
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> r >> c;
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++)
cin >> board[i][j];
}
bool visited[27] = {false};
visited[board[0][0] - 'A'] = true;
find(visited, 0, 0, 1);
cout << ans;
}