250x250
250x250
JinSeopKim
Hello World!
JinSeopKim
전체 방문자
오늘
어제
  • 분류 전체보기 (168)
    • Artificial intelligence (14)
      • DeepDiveToAI (3)
      • Pytorch (3)
      • Etc (8)
    • Back-end (19)
      • Spring (10)
      • JPA (9)
    • Language (24)
      • Python (3)
      • Java (11)
      • Swift (10)
    • Math (4)
      • Linear Algebra (4)
    • CodingTest (79)
      • Algolithm (12)
      • Backjoon (25)
      • Programmers (42)
    • Etc (27)
      • Book Review (3)
      • Adsp (6)
      • Life (2)
      • Docker (1)
      • odds and ends (15)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • GitHub

인기 글

태그

  • 선형대수
  • 카카오
  • 코딩테스트
  • swift
  • DP
  • 백준
  • JAVA8
  • ADsP
  • data
  • 개발
  • 머신러닝
  • BOJ
  • 자바
  • 프로그래머스
  • 구현
  • JPA
  • Python
  • 개발자
  • BFS
  • AI
  • 알고리즘
  • certificate
  • 브루트포스
  • ios
  • uArm
  • java
  • SpringMVC
  • 문제풀이
  • Front-end
  • 파이썬

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
JinSeopKim
CodingTest/Backjoon

[BOJ_16197] 두 동전 (java)

[BOJ_16197] 두 동전 (java)
CodingTest/Backjoon

[BOJ_16197] 두 동전 (java)

2022. 1. 11. 22:47
728x90
728x90

문제링크

https://www.acmicpc.net/problem/16197

 

16197번: 두 동전

N×M 크기의 보드와 4개의 버튼으로 이루어진 게임이 있다. 보드는 1×1크기의 정사각형 칸으로 나누어져 있고, 각각의 칸은 비어있거나, 벽이다. 두 개의 빈 칸에는 동전이 하나씩 놓여져 있고,

www.acmicpc.net

문제풀이

👨🏻‍💻 핵심 스킬 👨🏻‍💻
 브루트포스, 재귀

문제는 두 동전을 보드판에 올려놓고 상하좌우 중 한 곳으로 이동시켜 주어 하나의 동전만 떨어뜨리는 방법을 구하는 문제이다.

단, 동전이 움직일 때 벽을 만나게 되면 움직이지 못하며, 그 외의 경우에는 모두 움직여 줄 수 있다. 떨어지는 경우는 동전이 보드의 배열 밖으로 나가는(범위를 벗어나는) 경우가 된다.

 

이 문제를 브루트포스로 풀 수있다고 확신을 한 핵심은 10번보다 많이 눌러야 하면 수행을 못하는 것으로 판단하기 때문이다.  따라서 최대 10번만 움직일 수있다. 경우의 수를 고려하면 상,하,좌,우 4방향으로 10번만 움직이기 때문에 410410이 된다. 약 100만정도의 경우의 수이기 때문에 1초안에 문제를 해결하는데 큰 문제가 없어서 브루트포스로 모든 경우의 수를 조사해서 문제를 해결할 수 있다.

 

재귀로  모든 경우의수를 확인해줄 때 중요한 것은 몇번 옮겨졌는지와 현재 동전의 위치는 어디인지 이다.

재귀메소드의 종료 조건은 두 동전의 위치와 현재 옮겨진 횟수로 정해지기 때문이다. 만약 한개의 동전만 떨어졌다면 현재 얼마나 옮겼는지를 출력하면 되고, 동전이 두개가 동시에 떨어지거나,  두 동전의 위치가 같아지거나(같으면 어짜피 동시에 떨어지므로),10번이상 옮겨지는 경우는 옮길 수 없음을 표시해주어 종료해주면 된다.

 

재귀를 돌리는 방법은 상,하,좌,우로 벽이 아니라면 옮겨주고 확인하는 방법으로 실행해주면 된다.

구현코드

package boj_16197;

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        char[][] board = new char[n][m];
        int[][] coins = new int[2][2];

        int coinCheck = 0;
        for(int i = 0; i < n; i++){
            String input = sc.next();
            for(int j = 0; j < m; j++){
                board[i][j] = input.charAt(j);
                if(input.charAt(j) =='o'){
                    coins[coinCheck][0] = i;
                    coins[coinCheck][1] = j;
                    coinCheck++;
                }
            }
        }
        if(coinCheck == 2) {
            int resultValue = moveCoin(board, coins, 0);
            if (resultValue == Integer.MAX_VALUE) {
                System.out.println(-1);
            } else {
                System.out.println(resultValue);
            }
        }
        else
            System.out.println(-1);
    }

    public static int moveCoin(char[][] board, int[][] coins, int cnt){
        if(coins[0][0] < 0 || coins[0][0] >= board.length || coins[0][1] < 0 || coins[0][1] >= board[0].length){
            if(coins[1][0] < 0 || coins[1][0] >= board.length || coins[1][1] < 0 || coins[1][1] >= board[0].length)
                return -1;
            return cnt;
        }
        if(coins[1][0] < 0 || coins[1][0] >= board.length || coins[1][1] < 0 || coins[1][1] >= board[0].length){
            return cnt;
        }
        if(cnt == 10 || (coins[0][0] == coins[1][0] && coins[0][1] == coins[1][1])){
            return -1;
        }
        // 0 : 북 1 : 동 2 : 남 3 : 서 시계방향
        int[] dx = {-1,0,1,0};
        int[] dy = {0,1,0,-1};

        int min = Integer.MAX_VALUE;
        for(int i = 0; i < 4; i++){
            boolean coinOneMove = true;
            boolean coinTwoMove = true;
            coins[0][0] += dx[i];
            coins[0][1] += dy[i];
            coins[1][0] += dx[i];
            coins[1][1] += dy[i];

            if(!(coins[0][0] < 0 || coins[0][0] >= board.length || coins[0][1] < 0 || coins[0][1] >= board[0].length)
                    && board[coins[0][0]][coins[0][1]] == '#'){
                coinOneMove = false;
                coins[0][0] -= dx[i];
                coins[0][1] -= dy[i];
            }
            if(!(coins[1][0] < 0 || coins[1][0] >= board.length || coins[1][1] < 0 || coins[1][1] >= board[0].length)
                    && board[coins[1][0]][coins[1][1]] == '#'){
                coinTwoMove = false;
                coins[1][0] -= dx[i];
                coins[1][1] -= dy[i];
            }

            int value = moveCoin(board, coins, cnt + 1);
            if(value != -1){
                min = Math.min(value,min);
            }
            if(coinOneMove) {
                coins[0][0] -= dx[i];
                coins[0][1] -= dy[i];
            }
            if(coinTwoMove) {
                coins[1][0] -= dx[i];
                coins[1][1] -= dy[i];
            }
        }
        return min;
    }
}

 

시간복잡도

시간복잡도는 경우의 수를 고려하여 O(4n)O(4n)이라고 할 수 있다.

n : 이동하는 횟수 (1 <= n <= 10)

잘못된 지식이나 궁금한 내용이 있을 경우 편하게 댓글 남겨주시면 감사하겠습니다 :)

 

728x90
728x90
저작자표시 비영리 (새창열림)

'CodingTest > Backjoon' 카테고리의 다른 글

[BOJ_4574] 스도미노쿠 (java)  (0) 2022.01.12
BOJ_14888 연산자 끼워넣기 (Java)  (0) 2022.01.06
[BOJ_16931] 겉넓이 구하기 (java)  (0) 2021.12.31
[BOJ_2290] LCD Test (java)  (0) 2021.12.31
[BOJ_15685] 드래곤 커브 (Java)  (0) 2021.12.29
  • 문제링크
  • 문제풀이
  • 구현코드
  • 시간복잡도
'CodingTest/Backjoon' 카테고리의 다른 글
  • [BOJ_4574] 스도미노쿠 (java)
  • BOJ_14888 연산자 끼워넣기 (Java)
  • [BOJ_16931] 겉넓이 구하기 (java)
  • [BOJ_2290] LCD Test (java)
JinSeopKim
JinSeopKim
기록📚

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.