코딩테스트/백준_Java
Q. 1697 자바 : 숨바꼭질
Ski_
2023. 4. 8. 13:16
Q. 1697 자바 : 숨바꼭질
문제 : boj.kr/1697
실버 1 난이도의 문제이다.
두 점 N, K가 주어지고, N이 이동할 수 있는 방식은 총 3개이며 각각 1초가 소요된다면(N + 1, N - 1, N * 2)N이 K로 갈 수 있는 가장 빠른 시간을 구하는 문제이다.
만약 그래프 탐색 관련 문제를 풀고 있지 않았다면처음 이 문제를 봤을 때 그래프 탐색 문제라고 생각하지 못했을 것 같다.고민해보니 세가지 이동방식에 대한 BFS를 이용하면 풀 수 있을 것 같아 이 방식을 이용해서 풀었다.
1. 정점 N에서 이동 가능한 세 가지 방식에 따른 좌표를 큐에 넣는다.2. 만약 방문했다면 재방문하지 않는다.(가장 먼저 방문한 경우가 가장 빠른 경우이므로 재방문했다면 더 빨라질 수는 없다.)
시간복잡도를 계산하기 위해 범위를 찾아보니0 <= N ,K <= 100,000이므로 최악의 경우는 N이 100000, K가 0인 경우에-1을 이동하는 방식으로 100,000번 이동해야 K의 위치에 갈 수 있다.따라서 시간초과는 걱정하지 않아도 된다.
풀이는 아래와 같다.
import java.io.*;
import java.util.*;
public class Main {
static FastReader scan = new FastReader();
static StringBuilder sb = new StringBuilder();
static int N, K;
static int MAX_VALUE = 100000;
static int[] dist;
static boolean[] visit;
static void input() {
N = scan.nextInt();
K = scan.nextInt();
dist = new int[MAX_VALUE + 1];
visit = new boolean[MAX_VALUE + 1];
}
static void bfs(int s) {
Queue<Integer> que = new LinkedList<>();
que.add(s);
dist[s] = 0;
visit[s] = true;
while (!que.isEmpty()) {
int cur = que.poll();
int nx = cur + 1;
int ny = cur - 1;
int nz = cur * 2;
if (nx <= MAX_VALUE && !visit[nx]) {
que.add(nx);
visit[nx] = true;
dist[nx] = dist[cur] + 1;
}
if (ny >= 0 && !visit[ny]) {
que.add(ny);
visit[ny] = true;
dist[ny] = dist[cur] + 1;
}
if (nz <= MAX_VALUE && !visit[nz]) {
que.add(nz);
visit[nz] = true;
dist[nz] = dist[cur] + 1;
}
}
}
static void pro() {
bfs(N);
System.out.println(dist[K]);
}
public static void main(String[] args) {
input();
pro();
}
static class FastReader {
// BufferedReader의 빠른 속도,
// + Scanner의 타입별 입력값을 받는 기능을 혼합
// (자바 내부에 구현된 Scanner는 속도가 느림)
// 다른분의 코드를 참고한 코드
BufferedReader br;
StringTokenizer st;
public FastReader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
public FastReader(String s) throws FileNotFoundException {
br = new BufferedReader(new FileReader(new File(s)));
}
String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
long nextLong() {
return Long.parseLong(next());
}
double nextDouble() {
return Double.parseDouble(next());
}
String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
}
반응형