https://www.acmicpc.net/problem/18235
풀이
풀이를 쓸 생각이 없었는데, 1) 왠지 모르겠는데 난이도가 골드 3이나 되길래 인터넷에 검색해보니 2) 다들 이차원 dp로 풀이를 적길래 풀이를 작성합니다.
1. BFS
처음 Queue에 시작점, 도착점을 넣고, 각 단계마다 visited 배열을 초기화하여 한 단계 내에서 특정 지점을 두 번 방문하면 그 단계를 정답으로 출력하면 됩니다. 이진수의 특성 상 특정 점 s에서 x단계에 e로 가는 경우의 수는 (존재한다면) 유일하기에 가능한 풀이입니다.
2. 거리의 차로 풀기
(구사과님 풀이를 참고했습니다.)
오리와 육리가 있는데, x일차에 두 조류들의 거리의 차는
1) 오리와 육리가 서로 같은 방향으로 이동한다: 거리 차가 줄지 않습니다.
2) 오리와 육리가 반대 방향으로 이동한다: 거리 차이가 (1<<x)만큼 줄어들거나 늘어난다.
오리와 육리의 차이를 적당히 이진수로 나타냅시다. 예제 1을 생각해보면, 두 조류의 거리차는 110입니다.
(두 오리가 만난다) <=> (거리 차가 0이 된다)이므로, 각 자리를 0으로 만들어야 합니다.
(1<<x)번째 자리가 1이라면, (1<<x)번째 자리가 0이 되려면 x번째 날에 서로 다른 방향으로 움직여야 합니다.
반대로, (1<<x)번째 자리가 이미 0이라면 x번째 날에는 서로 같은 방향으로 이동해야 합니다.
코드
풀이 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
|
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int A = Integer.parseInt(st.nextToken());
int B = Integer.parseInt(st.nextToken());
if ((A-B) % 2 == 1) {
System.out.println(-1);
return;
}
int dist = 1;
int day = 0;
Queue<Integer> queue = new ArrayDeque<>();
queue.offer(A);
queue.offer(B);
while (!queue.isEmpty()) {
day++;
int size = queue.size();
boolean[] visited = new boolean[N+1];
while (size-- > 0) {
int cur = queue.poll();
int nxt = cur + dist;
if (nxt <= N) {
if (visited[nxt]) {
System.out.println(day);
return;
}
visited[nxt] = true;
queue.offer(nxt);
}
nxt = cur - dist;
if (nxt > 0) {
if (visited[nxt]) {
System.out.println(day);
return;
}
visited[nxt] = true;
queue.offer(nxt);
}
}
dist *= 2;
}
System.out.println(-1);
}
}
|
cs |
풀이 2
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
|
import java.io.*;
import java.util.*;
// 구사과님 풀이 참고함
public class Main {
static int ans = 100, N;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
int A = Integer.parseInt(st.nextToken());
int B = Integer.parseInt(st.nextToken());
if ((A-B) % 2 == 1) {
System.out.println(-1);
return;
}
dfs(A, B, 0);
System.out.println((ans == 100)? -1: ans);
}
static void dfs(int s, int e, int d) {
if (s <= 0 || s > N || e <= 0 || e > N) return;
if (s == e) {
ans = Math.min(ans, d);
return;
}
if (Math.abs(s-e) % (4 << d) == (2 << d)) {
dfs(s + (1<<d), e - (1<<d), d+1);
dfs(s - (1<<d), e + (1<<d), d+1);
} else {
dfs(s + (1<<d), e + (1<<d), d+1);
dfs(s - (1<<d), e - (1<<d), d+1);
}
}
}
|
cs |
'PS > BFS & DFS' 카테고리의 다른 글
백준 1525번: 퍼즐 (Java) (0) | 2022.09.04 |
---|---|
백준 2251번: 물통 (Java) (0) | 2022.09.02 |
백준 17090번: 미로 탈출하기 (Java) (0) | 2022.07.20 |
백준 2196번: 이진수 XOR (Java) (0) | 2022.06.27 |
백준 3179번: 백조의 호수 (JAVA) (0) | 2022.06.03 |