일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 스프링 핵심 원리 - 기본편
- 백준
- Kotlin in action 5장
- 백준 20055 컨베이어 벨트 위의 로봇
- 20055
- Kotlin in action 3장
- 7장 고급매핑
- Kotlin
- 코틀린
- KotlinInAction
- 13460 구슬탈출 2
- 객체 지향 설계와 스프링
- 20055 컨베이어 벨트 위의 로봇
- 자바 ORM 표준 JPA 프로그래밍 7장
- Kotlin In Action
- Kotlin in action 10장
- 싱글톤 컨테이너
- 코틀린인액션
- 고급매핑
- spring
- 스프링 핵심 원리 이해
- 기능개발 python
- 코틸린인액션
- 스프링 핵심 원리
- 백준 13460 Python
- Kotlin in action 6장
- 컨베이어 벨트 위의 로봇 Python
- 스프링 컨테이너와 스프링 빈
- kotlin in action 정리
- Python
- Today
- Total
기록하는 습관
[백준] 1697 숨바꼭질(BFS) 본문
문제
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다.
수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 구하는 프로그램을 작성하시오.
입력
첫 번째 줄에 수빈이가 있는 위치 N과 동생이 있는 위치 K가 주어진다. N과 K는 정수이다.
출력
수빈이가 동생을 찾는 가장 빠른 시간을 출력한다.
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define MAX 100001
using namespace std;
bool visit[MAX] = { false, };
void bfs(int start, int finish) {
queue<pair<int,int>> q;
int dist = 0; // 경과시간
pair<int,int> current;
q.push(make_pair(start,dist));
visit[start] = true; // 방문여부 check
while (!q.empty()) {
current = q.front();
q.pop();
if (current.first == finish) break; // 동생 찾을 시 break
dist = current.second + 1; // 1초씩 증가
// if문 안의 첫번째 조건은 배열 인덱스 참조 오류를 방지하기 위함(런타임에러 방지)이고,
// 두번째 조건은 한 번 방문한 노드는 재방문 하지 않게 하기 위함(메모리 초과 방지)
if (current.first * 2 <= MAX && !visit[current.first * 2]) { // * 2
q.push(make_pair(current.first * 2, dist));
visit[current.first * 2] = true;
}
if (current.first - 1 >= 0 && !visit[current.first - 1]) { // - 1
q.push(make_pair(current.first - 1, dist));
visit[current.first - 1] = true;
}
if (current.first + 1 <= MAX && !visit[current.first + 1]) { // + 1
q.push(make_pair(current.first + 1, dist));
visit[current.first + 1] = true;
}
}
printf("%d\n", current.second);
}
int main(void) {
int N, M;
cin >> N >> M;
bfs(N, M);
return 0;
}
이번 문제를 통해 코딩은 약간의 허술함도 용납하지 않는다는 것을 다시 깨달았다.
처음 메모리 초과는 문제를 한 번만 생각하고 두 번은 생각하지 않아서 발생한 오류.
visit 배열의 중요성!! -> 한 번 방문한 노드는 다시 방문하게 하지 않게 하기 위함이다.
만약 이 처리를 해주지 않는다면 BFS를 돌릴 때 나처럼 메모리 초과가 뜰 것이다..
그리고 런타임 에러는 배열의 인덱스 참조 오류로 인해 발생하였다.
current.first - 1과 같이 마이너스 연산에서는 0보다 작아질 경우를 방지해야 하는데 바보같이 <= MAX 로 해버렸다.
BFS를 이용하면 쉽게 풀 수 있는 문제!
-----------------------------------------------
[추가]
bfs 공부를 하다 더 간단한 코드가 있어서 참고하려고 붙인다.
굳이 큐를 pair로 만들지 않아도 while문을 돌리면서 time을 바로 반환해주면 된다.
int bfs(int n, int m) {
int time = 0;
queue<int> q;
q.push(n);
while(1) {
int size = q.size();
for(int i=0; i<size; i++) {
n = q.front();
q.pop();
if(n == m)
return time;
if(n > 0 && visit[n-1] == 0) {
q.push(n-1);
visit[n-1] = 1;
}
if(n < 100000 && visit[n+1] == 0) {
q.push(n+1);
visit[n+1] = 1;
}
if(n*2 <= 100000 && visit[n*2] == 0) {
q.push(n*2);
visit[n*2] = 1;
}
}
time++;
}
}
'알고리즘 > [문제풀이] 백준' 카테고리의 다른 글
[백준] DP - 1로 만들기 (0) | 2020.10.03 |
---|---|
[문제풀이] 경쟁적 전염 (0) | 2020.08.22 |
[백준] 2178 미로탐색 (0) | 2020.01.21 |
[백준] 1260 DFS와 BFS (0) | 2020.01.09 |
[백준] 10825 국영수 (0) | 2020.01.08 |