[백준 12851] 숨바꼭질 2 (C#, C++) - soo:bak
작성일 :
문제 링크
설명
수직선 위에서 수빈이와 동생의 초기 위치가 주어지고, 수빈이는 1초에 한 칸 앞으로, 한 칸 뒤로, 또는 현재 위치의 두 배 위치로 이동할 수 있을 때, 동생을 찾는 가장 빠른 시간과 그 시간으로 도달하는 방법의 수를 구하는 문제입니다.
수빈이와 동생의 초기 위치가 주어지며, 두 위치 모두 0 이상 100,000 이하입니다.
가장 빠른 시간을 첫째 줄에, 그 시간으로 동생을 찾는 방법의 수를 둘째 줄에 출력합니다.
접근법
각 이동이 1초씩 걸리므로 BFS를 사용하여 동생을 찾는 최단 시간을 구합니다.
최단 시간에 도달하는 방법의 수를 세기 위해, 방문 처리를 큐에서 꺼낸 후로 지연시켜 같은 시간에 목적지에 여러 경로가 도달할 수 있도록 합니다.
목적지에 처음 도착하면 그 시간을 최단 시간으로 기록하고, 이후 동일한 시간에 도착할 때마다 방법의 수를 증가시킵니다.
BFS는 시간 순서대로 탐색하므로, 최단 시간 이후에는 더 이상 경로를 세지 않아도 됩니다.
예를 들어, 수빈이가 5에 있고 동생이 17에 있다면 5 → 10 → 9 → 18 → 17, 5 → 4 → 8 → 16 → 17 등 서로 다른 경로로 4초에 도달할 수 있으며, 이러한 모든 방법의 개수를 세어 출력합니다.
Code
C#
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
using System;
using System.Collections.Generic;
namespace Solution {
struct Info {
public int pos, time;
}
class Program {
const int MAX = 100001;
static void Main(string[] args) {
var tokens = Console.ReadLine()!.Split();
var n = int.Parse(tokens[0]);
var k = int.Parse(tokens[1]);
var visited = new bool[MAX];
var q = new Queue<Info>();
q.Enqueue(new Info { pos = n, time = 0 });
visited[n] = true;
var minTime = 0;
var ways = 0;
while (q.Count > 0) {
var cur = q.Dequeue();
visited[cur.pos] = true;
if (minTime != 0 && minTime == cur.time && cur.pos == k) ways++;
if (minTime == 0 && cur.pos == k) {
minTime = cur.time;
ways++;
}
if (cur.pos + 1 < MAX && !visited[cur.pos + 1])
q.Enqueue(new Info { pos = cur.pos + 1, time = cur.time + 1 });
if (cur.pos - 1 >= 0 && !visited[cur.pos - 1])
q.Enqueue(new Info { pos = cur.pos - 1, time = cur.time + 1 });
if (2 * cur.pos < MAX && !visited[2 * cur.pos])
q.Enqueue(new Info { pos = 2 * cur.pos, time = cur.time + 1 });
}
Console.WriteLine(minTime);
Console.WriteLine(ways);
}
}
}
C++
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
#include <bits/stdc++.h>
using namespace std;
#define MAX 100001
struct Info {
int pos, time;
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int posSu, posSib; cin >> posSu >> posSib;
bool visited[MAX] = {false};
queue<Info> q;
q.push({posSu, 0});
visited[posSu] = true;
int minTime = 0;
int cntWay = 0;
while (!q.empty()) {
Info cur = q.front();
q.pop();
visited[cur.pos] = true;
if (minTime != 0 && minTime == cur.time && cur.pos == posSib) cntWay++;
if (minTime == 0 && cur.pos == posSib) {
minTime = cur.time;
cntWay++;
}
if (cur.pos + 1 < MAX && !visited[cur.pos + 1])
q.push({cur.pos + 1, cur.time + 1});
if (cur.pos - 1 >= 0 && !visited[cur.pos - 1])
q.push({cur.pos - 1, cur.time + 1});
if (2 * cur.pos < MAX && !visited[2 * cur.pos])
q.push({2 * cur.pos, cur.time + 1});
}
cout << minTime << "\n" << cntWay << "\n";
return 0;
}