1000 * 1000에 10000000번 산책을 하기때문에 시뮬레이션으로 접근하다가는 무조건 시간초과 뜹니다.
저는 방향정보를 dp를 이용하여 N - 1번까지 산책한 이후의 경로를 만들어 놓고 마지막 한 번 산책하는 방식으로 하였습니다.
dp에는 N - 1번의 산책동안 (x, y)에 몇 번 지나갔는지 표시하는데 사용하였습니다.
여기서 문제에서 산책하는 규칙이 있습니다.
0은 아래쪽, 1은 오른쪽 방향으로 가며 한 번 어떤 방향으로 가면 그 다음번 산책에서는 반드시 다른 방향으로 이동하게 되어있습니다.
따라서 dp[x][y]는 dp[x-1][y]에서 방문한 횟수의 1/2 + dp[x][y-1]에서 방문한 횟수의 1/2를 한 값입니다.
여기서 추가해야할 것이 dp[x-1][y], dp[x][y-1]이 홀수일 때 방향에 따라서도 방문횟수가 추가될 수 있습니다.
(x-1, y) 즉, 위쪽 방향에서 밑쪽으로 지나가려면 경로는 아래쪽 방향이 되어있어야합니다.
(x, y-1) 즉, 왼쪽 방향에서 오른쪽으로 지나가려면 경로는 오른쪽 방향이 되어있어야합니다.
위의 두가지를 추가하기 위해 처음에 받은 list[x-1][y], list[x][y-1]을 확인해야합니다.
(x-1, y)의 경우 처음 방향인 list[x-1][y]이 0이면 홀수일 때 1을 추가해줍니다.
(x, y-1)의 경우 처음 방향인 list[x][y-1]이 1이면 짝수일 때 1을 추가해줍니다.
이렇게 dp를 다 구하고 나면 이를 이용하여 산책경로를 모두 바꿔야합니다.
dp[x][y]가 짝수인 위치는 방향을 바꿀 필요 없고, 홀수인 위치에만 방향을 바꿔줍니다.
마지막으로 x=1, y=1에서부터 맵밖으로 산책을 즐기시면 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer st;
static int list[][] = new int[1001][1001];
static int H, W, N;
static void solve() {
int x = 1;
int y = 1;
while (true) {
if (list[x][y] == 1)
y++;
else
x++;
if (x > H || y > W)
break;
}
System.out.println(x + " " + y);
}
static void func() {
int dp[][] = new int[H + 1][W + 1];
for (int i = 1; i <= H; i++) {
for (int j = 1; j <= W; j++) {
if (i == 1 && j == 1) {
dp[i][j] = N - 1;
continue;
}
dp[i][j] = dp[i - 1][j] / 2 + dp[i][j - 1] / 2;
if (dp[i - 1][j] % 2 == 1 && list[i - 1][j] == 0)
dp[i][j]++;
if (dp[i][j - 1] % 2 == 1 && list[i][j - 1] == 1)
dp[i][j]++;
}
}
for (int i = 1; i <= H; i++) {
for (int j = 1; j <= W; j++) {
if (dp[i][j] % 2 == 0)
continue;
list[i][j] = 1 - list[i][j];
}
}
}
static void input() throws Exception {
st = new StringTokenizer(br.readLine());
H = Integer.parseInt(st.nextToken());
W = Integer.parseInt(st.nextToken());
N = Integer.parseInt(st.nextToken());
for (int i = 1; i <= H; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 1; j <= W; j++) {
list[i][j] = Integer.parseInt(st.nextToken());
}
}
}
public static void main(String[] args) throws Exception {
input();
func();
solve();
}
}
|
cs |
'algorithm > dp' 카테고리의 다른 글
boj 1010 다리 놓기 (0) | 2021.02.05 |
---|---|
boj 5557 1학년 (0) | 2021.02.05 |
boj 17528 Two Machines (0) | 2021.01.28 |
boj 9657 돌 게임 3 (0) | 2021.01.27 |
boj 2096 내려가기 (0) | 2021.01.22 |