일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Overfitting
- 문자열
- BFS
- NEXT
- back propagation
- 너비 우선 탐색
- tensorflow
- 다익스트라
- 조합론
- 자바스크립트
- 회고록
- 분할 정복
- object detection
- 세그먼트 트리
- 가끔은 말로
- dropout
- 가끔은_말로
- 플로이드 와샬
- 우선 순위 큐
- 알고리즘
- 크루스칼
- 2023
- c++
- DP
- dfs
- pytorch
- lazy propagation
- 백트래킹
- 미래는_현재와_과거로
- 이분 탐색
Archives
- Today
- Total
Doby's Lab
[알고리즘] 백준 14562번: 태권왕 (C++), 범위 오류 본문
https://www.acmicpc.net/problem/14562
이번 문제를 풀면서 저번에 포스팅했던 리모컨 문제가 떠올랐었다.
(https://draw-code-boy.tistory.com/99)
솔루션
간단한 BFS 문제였다. S와 T의 점수가 주어지면 두 가지 방법으로 S의 점수를 올려준다.
- S의 점수가 2배가 된다. 단, T의 점수에는 3점이 추가된다.
- S의 점수에 1점이 추가된다.
두 가지 경로를 가지고 BFS를 짜주면 된다.
단, 이번 문제에서 주의해야 할 사항이 2가지 존재한다.
1) 한 번 나온 스코어는 건드리지 않는다.
예를 들어, 2 : 4 가 나오고 있다 치면 다른 경로를 통해서도 2 : 4 가 나오는 경우가 있다.
둘 중에 더 빠른 경로가 나온 이상 다신 2 : 4라는 점수를 건드리지 않도록 한다.
>> 최솟값을 구하는 과정
아래는 BFS에서 경로 탐색의 조건을 가져온 부분이다.
if문에서
score[y * 2][x + 3] == 0
score[y + 1][x] == 0
두 조건들이 다신 건드리지 않게 해주는 조건에 해당된다.
if (y * 2 < MAX && x + 3 < MAX && score[y * 2][x + 3] == 0) {
q.push(make_pair(y * 2, x + 3));
score[y * 2][x + 3] = score[y][x] + 1;
}
if (y + 1 < MAX && x < MAX && score[y + 1][x] == 0) {
q.push(make_pair(y + 1, x));
score[y + 1][x] = score[y][x] + 1;
}
2) 범위를 잘 생각해봐야 한다.
문제에서는 S와 T가 100 이하의 수로 주어진다고 되어있다. 그렇다고 해서 점수 또한 100까지만 올릴 수 있는 건 아니라고 생각해야 한다. (이번 포스팅의 이유)
만약 저 생각을 못 하고서 코드를 짠다면 다음 반례가 존재한다.
[input]
1
1 100
[output]
99
[answer]
10
100까지만 잡았을 때는 100에서 점수가 안 올라가므로 1에서부터 1점씩 밖에 못 올려서 99번이 된다.
하지만, 조금 넉넉하게 200까지 잡아주면 10이라는 답을 도출할 수 있다.
>> 점수가 100을 넘길 수도 있다는 생각을 할 수 있어야 한다.
[범위 설정 오류 코드]
#include <iostream>
#include <queue>
#include <utility>
using namespace std;
int T;
int score[101][101] = { 0, };
void reset() {
for (int i = 1; i <= 100; i++) {
for (int j = 1; j <= 100; j++) {
score[i][j] = 0;
}
}
}
int bfs(int s1, int s2) {
queue<pair<int, int>> q;
q.push(make_pair(s1, s2));
while (!q.empty()) {
int y = q.front().first;
int x = q.front().second;
if (y == x) {
return score[y][x];
}
q.pop();
if (y * 2 <= 100 && x + 3 <= 100 && score[y * 2][x + 3] == 0) {
q.push(make_pair(y * 2, x + 3));
score[y * 2][x + 3] = score[y][x] + 1;
}
if (y + 1 <= 100 && x <= 100 && score[y + 1][x] == 0) {
q.push(make_pair(y + 1, x));
score[y + 1][x] = score[y][x] + 1;
}
}
}
int main() {
cin >> T;
for (int t = 1; t <= T; t++) {
int s1, s2;
cin >> s1 >> s2;
cout << bfs(s1, s2) << '\n';
reset();
}
return 0;
}
[AC 코드]
#include <iostream>
#include <queue>
#include <utility>
using namespace std;
#define MAX 200 + 1
int T;
int score[MAX][MAX] = { 0, };
void reset() {
for (int i = 0; i < MAX; i++) {
for (int j = 0; j < MAX; j++) {
score[i][j] = 0;
}
}
}
int bfs(int s1, int s2) {
queue<pair<int, int>> q;
q.push(make_pair(s1, s2));
while (!q.empty()) {
int y = q.front().first;
int x = q.front().second;
if (y == x) {
return score[y][x];
}
q.pop();
if (y * 2 < MAX && x + 3 < MAX && score[y * 2][x + 3] == 0) {
q.push(make_pair(y * 2, x + 3));
score[y * 2][x + 3] = score[y][x] + 1;
}
if (y + 1 < MAX && x < MAX && score[y + 1][x] == 0) {
q.push(make_pair(y + 1, x));
score[y + 1][x] = score[y][x] + 1;
}
}
}
int main() {
cin >> T;
for (int t = 1; t <= T; t++) {
int s1, s2;
cin >> s1 >> s2;
cout << bfs(s1, s2) << '\n';
reset();
}
return 0;
}
728x90
'PS > BOJ' 카테고리의 다른 글
[자료구조] 백준 1918번: 후위 표기식 (C++), stack의 특성 LIFO (0) | 2021.11.20 |
---|---|
[알고리즘] 백준 2206번: 벽 부수고 이동하기 (C++), 새로운 유형 BFS + Greedy (0) | 2021.11.20 |
[알고리즘] 백준 2407번: 조합 (C++), Combination, Permutation (0) | 2021.11.18 |
[알고리즘] 백준 9465번: 스티커 (C++), 논리와 직관 그 어디쯤 사이에 (0) | 2021.11.18 |
[알고리즘] 백준 1107번: 리모컨 (C++), 모든 경우의 수 (0) | 2021.11.17 |