https://www.acmicpc.net/problem/19940
처음 이문제를 봤을때 N의 범위가 10000000이라 set을 써야하나 고민했었습니다.
근데 한 번에 이동할 수 있는건 (+60, +10, -10, +1, -1) 이렇게 5개밖에 없기 때문에 언제 1000만을 찍나 고민했습니다.
일단 바로 알수있는건 N이 클수록 +60을 많이 누르는게 이득이지 않을까 생각하여 bfs에 greedy까지 생각하게 되었습니다.
여기까지 오셨다면 문제를 쉽게 해결할 수 있습니다.
N을 60으로 나눈다면 우리가 할건 0 ~ 59까지의 최소 횟수만 구하면 됩니다.
방문처리는 N에 대해서만 해주시면 되고, queue에는 N과 버튼 누른 횟수를 모두 넣어줬습니다.
문제에서 횟수가 동일하다면 (-1 > +1 > -10 > +10 > +60) 순으로 높은 우선순위를 부여한다고 명시되어 있기 때문에
연산의 순서 또한 (-1 -> +1 -> -10 -> +10 -> +60) 으로 진행합니다.
다음에는 N을 입력받고, +60에는 N / 60을 더해주고, 나머지는 미리 구했던 값을 그대로 출력해주시면 되겠습니다.
개인적으로 이 문제 어렵다고 느껴졌는데 골드5 더라고요..?
난이도 기여하러 갔더니 다들 쉽다는 반응은 아니었는데 골드5를 주셨더라고요..??
난 어렵게 느껴졌는데.. 골드4보다 더 주고싶었는데.. 그냥 그렇다고요..
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
|
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define MAX 61
using namespace std;
bool visit[MAX];
int btns[5] = { 60, 10, -10, 1, -1 };
vector<int> ret[MAX];
int N;
void bfs() {
queue<pair<int, vector<int>> > q;
ret[0] = vector<int>(5, 0);
q.push({ 0,ret[0] });
visit[0] = true;
while (!q.empty()) {
auto now = q.front();
q.pop();
for (int d = 4; d >= 0; d--) {
int next = now.first + btns[d];
if (next < 0 || next > 60) continue;
if (visit[next]) continue;
visit[next] = true;
ret[next] = now.second;
ret[next][d]++;
q.push({ next, ret[next] });
}
}
}
void func() {
int x = N / 60;
int y = N % 60;
cout << x + ret[y][0] << ' ' << ret[y][1] << ' ' << ret[y][2] << ' ' << ret[y][3] << ' ' << ret[y][4] << '\n';
}
void input() {
cin >> N;
}
int main() {
cin.tie(NULL); cout.tie(NULL);
ios::sync_with_stdio(false);
bfs();
int tc;
cin >> tc;
while (tc--) {
input();
func();
}
return 0;
}
|
cs |
'algorithm > bfs' 카테고리의 다른 글
boj 22944 죽음의 비 (0) | 2024.07.18 |
---|---|
boj 27211 도넛 행성 (2) | 2024.07.17 |
boj 2310 어드벤처 게임 (0) | 2024.06.25 |
boj 2412 암벽 등반 (0) | 2024.06.22 |
boj 14497 주난의 난(難) (0) | 2024.06.21 |