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

 

5573번: 산책

문제 상근이는 건강을 위해 산책을 하려고 한다. 상근이가 사는 마을은 아래 그림과 같이 가로 방향 도로가 (H+1)개, 세로 방향 도로가 (W+1)개가 바둑판 모양으로 배치되어 있다. 상근이네 집은 가장 왼쪽 위 교차로에 있으며, 이곳에서 산책을 시작한다. (a,b)는 위쪽에서 a번째, 왼쪽에서 b번째에 있는 교차로이다. 예를 들어, 상근이네 집은 교차로 (1,1)에 있다. 상근이는 산책 경로가 매일 달라야 질리지 않고 산책을 할 수 있다고 생각한다. 따

www.acmicpc.net


문제해설

H와 W의 입력자체가 1000까지 들어오지만, N이 10^7까지 들어오기 때문에,

일반적인 시뮬레이션으로는 해결 할 수없어 보입니다.

총 N번 산책을 했을 때, 어떤 교차점에대해서 몇번 지나게 되는가를 미리 계산하면 됩니다.

(1,1) 정점은 N번 산책을 할 경우 N번 지나게 될 것입니다.

(1,2)는 대략적으로 N/2

(2,1)도 대략적으로 N/2

...

이런식으로 dp 테이블을 생성해 나아가면 됩니다.

 

< 예시 >

W = 1, H = 1 인 케이스에서 N 이 주어졌다고 생각해봅시다.

N번 산책동안 1,1를 N번 지나게됨으로

N번 산책일때 오른쪽으로 가는가, 왼쪽으로 가는가만 계산하면 될텐데

첫 입력에서 (오른쪽)이 주어졌다면

짝수번 방문할 경우는 (2,1)

홀수번 방문할 경우는(1,2)

에 도착하게됩니다.

 

W = 2, H = 2인 케이스에서 N이 주어졌다고 생각해봅시다.

N이만약 짝수라면

dp[1][1] = N번

dp[2][1] = dp[1][1]/2

dp[1][2] = dp[1][1]/2

dp[2][2] = dp[1][2]/2 + dp[2][1]/2

가 될 것입니다. 

 

위의 같은케이스에서 N이홀 수라면 

처음 입력에 따라서 오른쪽이나 아래쪽에 1이 더큰 숫자가 들어가게 될 것입니다.


 DP 테이블을 완성한뒤에

mod2 연산을 하게 되었을때 dp 테이블에 남은 숫자가 곧

방향을 알려줄 것이고

DFS를 통해 결과를 구 할 수 있습니다.


전체코드

#include <iostream>
using namespace std;

int arr[1001][1001];
int dp[1001][1001];
int R, C, N;
pair<int, int> ans;

void DFS(int r, int c) {
	if (r >= R || c >= C) {
		ans = { r,c };
		return;
	}
	if (arr[r][c] == 1) {
		if (dp[r][c] == 1) 
			DFS(r, c + 1);
		else 
			DFS(r + 1, c);
	}
	else {
		if (dp[r][c] == 1)
			DFS(r+1, c);
		else 
			DFS(r, c+1);
	}
}


int main() {
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin >> R >> C >> N;
	for (int i = 0; i < R; i++) {
		for (int j = 0; j < C; j++) {
			cin >> arr[i][j];
		}
	}

	dp[0][0] = N;
	for (int i = 0; i < R; i++) {
		for (int j = 0; j < C; j++) {
			if (arr[i][j] == 1) {
				dp[i+1][j] += dp[i][j] / 2;
				dp[i][j+1] += (dp[i][j] % 2 == 0) ? dp[i][j] / 2 : dp[i][j] / 2 + 1;
			}
			else {
				dp[i+1][j] += (dp[i][j] % 2 == 0) ? dp[i][j] / 2 : dp[i][j] / 2 + 1;
				dp[i][j + 1] += dp[i][j] / 2;
			}
		}
	}

	for (int i = 0; i < R; i++) {
		for (int j = 0; j < C; j++) {
			dp[i][j] %= 2;
		}
	}
	DFS(0, 0);
	cout << ++ans.first  << " " << ++ans.second << "\n";
}

 

 

'알고리즘 > [C++]BOJ' 카테고리의 다른 글

[백준BOJ] 13306 트리  (0) 2019.10.09
[백준BOJ] 10774 저지  (0) 2019.10.07
[백준BOJ] 5012 불만 정렬  (0) 2019.10.07

+ Recent posts