[백준,BOJ 1697] 숨바꼭질(JAVA 구현, 추가풀이)

2020. 11. 13. 16:20·CodingTest/백준 온라인 저지(BOJ)
반응형

-내 생각

  일단 이 문제를 풀었을 때 굉장히 뿌듯했다. 왜냐하면 알고리즘 공부를 막 시작했을 때 이와 비슷한 문제를 만나서 어떻게 해결해야 할지 감도 안 잡히고 노트만 더러워졌었는데, 이번엔 풀어냈다. 그렇다고 이 문제를 처음 봤을 때 딱 해결법이 떠오른 것은 아니었다.

 

  우선 고민을 해보았다. 예제 입력에서 수빈이의 첫 위치가 5이기 때문에 5에서 1일이 지날 때 갈 수 있는 곳은 4, 6, 10이다. 이와 같이 그래프를 그려서 생각해보니 어느 정도 윤곽이 잡혔고, 이전에 풀었던 토마토 문제나 최단경로 찾는 문제처럼 방문 여부배열에 1씩 증가시키면 될 것 같다는 생각까지는 했는데 조건문 부분에서 고민을 많이 했다. 왜냐하면 문제에서 동생을 찾을 수 있는 가장 빠른 시간을 묻기 때문에 최솟값을 찾아야 한다는 강박에 쌓인 것이다. 하지만 이 부분에 대한 해결은 간단했다. 방문 배열에 최초 0으로 초기화 되어있는 상태에서 0이면 입력하고 이미 입력되어있으면 갱신하지 않는 것이다. 그러면 자동적으로 최솟값이 적용될 것인데 말이다. 

 

-해법

  해법은 코드를 보면서 이해해 보자.

 

import java.util.*;

public class Main {
	
	static int check[]; // 방문여부 배열
		
	public static void bfs(int a,int k) { //BFS메소드, 수빈이의 위치와 동생의 위치를 전달
		Queue<Integer> queue = new LinkedList();
		
		check[a] = 0; // 수빈이의 위치를 0으로 초기화
		queue.offer(a); 
		
		while(!queue.isEmpty()) { //큐가 빌 때 까지 반복한다.
			int x = queue.poll();
			if(check[k]!=0) break; // 그러나 동생의 위치값이 0이 아니면 이미 최솟값을 찾은 것이므로 벗어난다.
								   // 배열의 크기를 100,001로 해서 시간을 조금이라도 단축시키기 위함
			if((x-1>=0) && check[x-1]==0) { // 이 부분에서 많은 분들이 런타임 에러가 많이 발생하는 것 같다.
				queue.offer(x-1);  			// 조건부의 x범위를 먼저 확인해줘야 뒤에 배열 인덱스를 참조할 때 범위를 벗어나지 않는다.
				check[x-1] = check[x]+1; //이동할 수 있는 경우 x-1
			}
			if((x<check.length-1)&&check[x+1]==0) {
				queue.offer(x+1);
				check[x+1] = check[x]+1; //이동할 수 있는 경우 x+1
			}
			if((x*2<check.length)&&check[2*x]==0) {
				queue.offer(2*x);
				check[2*x] = check[x]+1; //이동할 수 있는 경우 순간이동 x*2
			}
			
		}	
	}
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);	
		
		int n = sc.nextInt(); // 수빈이 위치
		int k = sc.nextInt(); // 동생 위치
		check = new int [100001]; // 수빈이와 동생이 위치할 수 있는 범위는 0 ~ 100,000이다.
		
		
		if(n==k) { // 만약 수빈이와 동생의 위치가 같다면 이동할 필요가 없다.
			System.out.println("0"); // 이 부분에서 오답처리를 받았다. 예외의 경우를 항상 생각하자.
			return;
		}
		bfs(n,k); // bfs로 수빈이와 동생의 위치를 전달한다.
		
		System.out.println(check[k]); // 수빈이 위치 인덱스 값을 출력한다.
		
		
		
		
		
	}
	
}

  이 문제 역시 풀이는 위와 비슷하게 하였지만, 

if(n+1 >=check.length || n-1<0 || n*2 >= check.length) continue;

  BFS 메소드 내의 조건을 거는 과정에서 한 번에 저렇게 처리하려 하였지만, 세 가지 조건 중 하나에만 걸려도 큐가 비어버리는 경우가 발생할 수 있는 것을 간과하였다. 따라서 아래처럼

if(n+1 <check.length&& check[n+1] == 0) {
  check[n+1] =check[n]+1;
  q.offer(n+1);
}
if( n-1>=0 && check[n-1] == 0) {
  check[n-1] = check[n]+1;
  q.offer(n-1);
}
if( n*2 < check.length && check[n*2] == 0) {
  check[n*2] = check[n]+1;
  q.offer(n*2);
}

  조건문마다 일치 범위를 지정해 주어 세 가지 조건들이 서로 영향을 받지 않게 작성하였다. 아래는 전체 코드이다.

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

class Main {
		
	static void bfs(int[] check,int x,int k) {
		Queue<Integer> q = new LinkedList<>();
	
		q.offer(x);
		check[x] = 0;
		
		while(!q.isEmpty()) {
			int n = q.poll();
							
			if (check[k] != 0) break;
			
			//if(n+1 >=check.length || n-1<0 || n*2 >= check.length) continue;
			
			if(n+1 <check.length&& check[n+1] == 0) {
				check[n+1] =check[n]+1;
				q.offer(n+1);
			}
			if( n-1>=0 && check[n-1] == 0) {
				check[n-1] = check[n]+1;
				q.offer(n-1);
			}
			if( n*2 < check.length && check[n*2] == 0) {
				check[n*2] = check[n]+1;
				q.offer(n*2);
			}
			
		}
	}
	
	public static void main(String[] args)  {
		Scanner in = new Scanner(System.in);
		
		int n = in.nextInt();
		int k = in.nextInt();		
		
		int check[] = new int[100001];	
		
		if(n == k) {
			System.out.println(0);
			return;
		}
		
		bfs(check,n,k);
		
		System.out.println(check[k]);
		
	}
}
저작자표시 (새창열림)
'CodingTest/백준 온라인 저지(BOJ)' 카테고리의 다른 글
  • [백준,BOJ 15649] N과 M(2) (JAVA 구현,추가풀이)
  • [백준,BOJ 2206] 벽 부수고 이동하기(JAVA 구현,추가풀이)
  • [백준,BOJ 7569] 토마토2(JAVA 구현,추가풀이)
  • [백준,BOJ 7576] 토마토(JAVA 구현, 추가풀이)
뜸부깅
뜸부깅
코딩에 대한 여러 개인적인 생각을 정리하고 공부를 하는 공간입니다!!
  • 뜸부깅
    코오오딩
    뜸부깅
  • 전체
    오늘
    어제
    • Note (429)
      • Skill (31)
        • Java & Spring (9)
        • Javascript & HTML & CSS (0)
        • React (0)
        • Next.js (22)
      • CodingTest (389)
        • 백준 온라인 저지(BOJ) (140)
        • 프로그래머스(Programmers) (79)
        • LeetCode (170)
      • Algorithm & Data Structure (6)
      • [Project] 포트폴리오 (3)
        • Front end (3)
        • Back end (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    백준2751
    TypeScript
    백준7576
    medium
    meidum
    백준1260
    component-scan
    BOJ
    Easy
    백준1427
    Java
    자바
    알고리즘
    next 14
    백준7576자바
    프로그래머스
    boj2108
    leetcode 2236
    boj1427
    백준
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
뜸부깅
[백준,BOJ 1697] 숨바꼭질(JAVA 구현, 추가풀이)
상단으로

티스토리툴바