백준 1103번 게임
< 백준 1103번 게임 - 마포 코딩박 >
사용한 알고리즘: DFS + DP
Grid 의 칸마다 숫자가 주어지고, 상하좌우로 그 숫자만큼 이동한다. 이때 최대 이동 가능수를 구한다. 처음 시작하는 지점은 왼쪽위(0,0) 지점이다.
처음 시작도 1번으로 카운트 해줘야 한다.
처음 시작을 0번으로 하고, 대신 마지막에 Grid밖으로 움직이는 것을 +1번으로 카운트 해주었다.
문제풀이는 다음과 같다.
(1) (코드: 12~36)
시작위치 (0,0) 에서 DFS를 사용해 상하좌우로 탐색해주었다.
(2) (코드: dp[50][50])
dp[i][j] : (i,j) 위치에서 최대 이동가능 횟수 로 저장해주어, 반복적인 탐색을 피해줬다.
(3) (코드: visited[50][50])
이미 방문했던 위치를 다시 방문할 경우, cycle이 생긴 경우이다. 즉 동전을 무한대로 움직일 수 있는경우이다. 이를 체크해주어 이경우 -1을 출력해주었다.
사용한 알고리즘: DFS + DP
Grid 의 칸마다 숫자가 주어지고, 상하좌우로 그 숫자만큼 이동한다. 이때 최대 이동 가능수를 구한다. 처음 시작하는 지점은 왼쪽위(0,0) 지점이다.
처음 시작도 1번으로 카운트 해줘야 한다.
처음 시작을 0번으로 하고, 대신 마지막에 Grid밖으로 움직이는 것을 +1번으로 카운트 해주었다.
문제풀이는 다음과 같다.
(1) (코드: 12~36)
시작위치 (0,0) 에서 DFS를 사용해 상하좌우로 탐색해주었다.
(2) (코드: dp[50][50])
dp[i][j] : (i,j) 위치에서 최대 이동가능 횟수 로 저장해주어, 반복적인 탐색을 피해줬다.
(3) (코드: visited[50][50])
이미 방문했던 위치를 다시 방문할 경우, cycle이 생긴 경우이다. 즉 동전을 무한대로 움직일 수 있는경우이다. 이를 체크해주어 이경우 -1을 출력해주었다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <bits/stdc++.h> | |
using namespace std; | |
// 0,0 에서 시작 | |
int N, M, ans, dp[50][50]; | |
char arr[50][50]; | |
// 위 오른쪽 아래 왼쪽 | |
int dx[4] = {-1,0,1,0}; | |
int dy[4] = {0,1,0,-1}; | |
bool visited[50][50]; | |
bool circle; | |
int DFS(int x, int y){ | |
// Grid 밖 | |
if(x<0||x>=N||y<0||y>=M) return 0; | |
// 홀로 빠짐 | |
if(arr[x][y]=='H') return 0; | |
// cycle 생기면 체크 | |
if(visited[x][y]){ | |
circle = true; | |
return -1; | |
} | |
int &ret = dp[x][y]; | |
// 값을알면 해당 값 출력 (dp) | |
if(ret!=-1) return ret; | |
visited[x][y] = true; | |
// 상하좌우 탐색 | |
for (int i = 0; i < 4; ++i){ | |
int nx = x + (arr[x][y]-'0')*dx[i]; | |
int ny = y + (arr[x][y]-'0')*dy[i]; | |
// 첫 시작을 0으로 했으니 마지막에 Grid밖으로 움직인것을 대신 카운트 +1번 | |
ret = max(ret, DFS(nx,ny)+1); | |
} | |
// 다음으로 빠져나가기 전 지금 본 경로 reset | |
visited[x][y] = false; | |
return ret; | |
} | |
int main(){ios_base::sync_with_stdio(false); cout.tie(NULL); cin.tie(NULL); | |
cin >> N >> M; | |
for (int i = 0; i < N; ++i) | |
for (int j = 0; j < M; ++j) | |
cin >> arr[i][j]; | |
memset(dp,-1,sizeof(dp)); | |
ans = DFS(0,0); | |
if(circle) cout << -1 << '\n'; | |
else cout << ans << '\n'; | |
return 0; | |
} |
댓글
댓글 쓰기
긴 글 읽어주셔서 감사합니다.
궁금한게 있으시다면 댓글 달아주세요!