Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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
- 데이터베이스
- 코딩테스트 [ ALL IN ONE ]
- Git
- 운영체제
- 온디바이스AI
- 반효경
- concurrency control
- 쉬운 코드
- 인터럽트
- 코딩애플
- 시스템프로그래밍
- 갤럭시 S24
- recoverability
- vite
- 백엔드
- 개발남노씨
- BreadcrumbsComputer-Networking_A-Top-Down-Approach
- SQL
- Extendable hashing
- 네트워크
- 트랜잭션
- 시그널 핸들러
- 김영한
- B tree 데이터삽입
- 커널 동기화
- 쉬운코드
- 프로세스 주소 공간
- SDK
- 운영체제와 정보기술의 원리
- CPU 스케줄링
Archives
- Today
- Total
티끌모아 태산
12851: 숨바꼭질 2 본문
728x90
https://www.acmicpc.net/problem/12851
12851번: 숨바꼭질 2
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때
www.acmicpc.net
설명
수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다.
수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지 그리고, 가장 빠른 시간으로 찾는 방법이 몇 가지 인지 구하는 프로그램을 작성하시오.
핵심 아이디어
- 두 개의 위가 주어졌을 때, 한 위치에서 다른 위치로 이동하는 가장 빠른 시간과 방법을 구하는 문제이므로 BFS 탐색 알고리즘을 떠올리면 좋다.
- x-1, x+1, x*2 를 고려해서 범위 내에 있고, 방문하지 않았거나 방문 했더라도 이전 지점에서 재방문 할 수 있을 경우의 조건을 넣어야 한다.
- 그리고 K값이 되면, 방문 거리와 방문 횟수를 저장해 주었다. 그리고 연산이 처음부터 돌아가야 하므로 continue를 넣어 주었다. (continue를 넣지 않으면 중간 테스트케이스에서 틀려버린다.)
코드 구현
Python
import sys
input = sys.stdin.readline
from collections import deque
start, k = map(int, input().split())
distance = [0] * 100001 # 최대 0부터 100000지점까지 걸리는 횟수 기록
#bfs 탐색 알고리즘
q = deque()
q.append(start) # 수빈이가 있는 시작 위치
min_distance = 0 # 최적 시간
cnt = 0 # 최적의 경로의 수
while q:
x = q.popleft()
# 도작 지점이라면 탐색 종료
if x == k: # 방문 시간과 방문 횟수 저장
min_distance = distance[x]
cnt += 1
continue # 다른 최단 방법을 찾기 위해 연산을 처음부터 하기 위함
for next in (x+1, x-1, x*2):
# 주어진 범위를 벗어나지 않고, 방문하지 않았거나 다음 지점 의 최단 거리가
# 이전 지점 + 1 이라면 즉, 동일한 최단 거리 기록을 갖는 곳
# 중요한 점은 동일한 탐색 횟수를 가진 곳도 재탐색 해야한다.
# 이를 통해 이미 탐색 했던 곳도 포함해서 다양한 최단 경로 탐색 가능
if (0<= next <= 100000) and (distance[next] == 0 or
distance[next] == distance[x] + 1):
distance[next] = distance[x] + 1 # 방문하고 횟수 1 늘림
q.append(next)
print(min_distance)
print(cnt)
C++
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
int start, k;
vector<int> distance; // 최대 0부터 100000까지의 횟수 기록
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> start >> k;
// distance 초기화
vector<int> distance(100001, 0);
// 큐 구현을 위해 deque 사용
queue<int> q;
q.push(start); // 수빈이가 있는 시작 위치
int min_distance = 0; // 최적 시간
int cnt = 0; // 최적의 경로의 수
while (!q.empty()) {
int x = q.front();
q.pop();
// 도착 지점이라면
if (x == k) {
min_distance = distance[x]; // 첫 도착 시간 기록
cnt++; // 같은 최단 거리일 경우 카운트 증가
continue;
}
for (int next : {x + 1, x - 1, x * 2}) {
// 주어진 범위를 벗어나지 않고, 방문하지 않았거나
// 다음 지점의 최단 거리가 이전 지점 + 1 이라면
if (0 <= next && next <= 100000 &&
(distance[next] == 0 || distance[next] == distance[x] + 1)) {
distance[next] = distance[x] + 1; // 방문 하고 횟수 1 늘림
q.push(next);
}
}
}
cout << min_distance << "\n";
cout << cnt << "\n";
return 0;
}
여기서 중요한 점은 '동일한 탐색 횟수를 가진 곳'도 탐색한다는 것이다. 즉 이미 탐색 했던 곳도 포함해서 다양한 최단 경로를 탐색할 수 있다. 그렇지 않으면, 앞선 최단 경로가 지나간 경로는 사용할 수 없으므로 모든 경우의 수를 구할 수 없다.
728x90
'백준 문제 > BFS,DFS' 카테고리의 다른 글
2178: 미로 탐색 (0) | 2024.03.25 |
---|---|
[필수]백준: 컴백홈_1189 (0) | 2024.02.14 |
[필수]백준: 치즈_2636 (1) | 2024.02.01 |