쵼쥬
쵼쥬의 개발공부 TIL
쵼쥬
전체 방문자
오늘
어제
  • 분류 전체보기 (276)
    • 코딩테스트 (192)
      • [알고리즘] 알고리즘 정리 (7)
      • [백준] 코딩테스트 연습 (126)
      • [프로그래머스] 코딩테스트 연습 (59)
    • Spring (71)
      • [인프런] 스프링 핵심 원리- 기본편 (9)
      • [인프런] 스프링 MVC 1 (6)
      • [인프런] 스프링 MVC 2 (4)
      • [인프런] 실전! 스프링 부트와 JPA 활용1 (7)
      • [인프런] 실전! 스프링 부트와 JPA 활용2 (5)
      • [인프런] 실전! 스프링 데이터 JPA (7)
      • [인프런] 실전! Querydsl (7)
      • JWT (5)
      • [인프런] Spring Cloud (17)
      • [인프런] Spring Batch (4)
    • Java (6)
      • [Java8] 모던인자바액션 (4)
      • [부스트코스] 웹 백엔드 (2)
      • [패스트캠퍼스] JAVA STREAM (0)
    • CS (6)
      • 디자인 패턴과 프로그래밍 패터다임 (2)
      • 네트워크 (4)

블로그 메뉴

  • 홈

공지사항

인기 글

태그

  • 누적합
  • jpa
  • 타임리프
  • 위클리 챌린지
  • 구현
  • 백준
  • 프로그래머스
  • BFS
  • 알고리즘
  • 자바
  • 스프링
  • 백분
  • querydsl
  • spring
  • 인프런
  • MVC
  • Spring Data JPA
  • 비트마스킹
  • 부스트코스
  • 코딩테스트

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
쵼쥬

쵼쥬의 개발공부 TIL

통나무 옮기기
코딩테스트/[백준] 코딩테스트 연습

통나무 옮기기

2022. 3. 10. 16:11


내 코드

package com.company;

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = null;

        int answer = 0;
        int N = Integer.parseInt(br.readLine());
        char[][] arr = new char[N][N];
        ArrayList<int[]> listB = new ArrayList<>();     // 초기 통나무
        ArrayList<int[]> listE = new ArrayList<>();     // 목적지
        boolean[][][] visited = new boolean[N][N][2];   // 방문 체크 ( 0 : 가로, 1: 세로)

        // 움직임 (U, D, L, R, T)
        int[][][] d = {{{-1, 0}, {-1, 0}, {-1, 0}}, {{1, 0}, {1, 0}, {1, 0}}, {{0, -1}, {0, -1}, {0, -1}},
                {{0, 1}, {0, 1}, {0, 1}}, {{-1, -1}, {0, 0}, {1, 1}}};
        int[][] rotation = {{1, 1}, {-1, -1}, {1, -1}, {-1, 1}};    // 회전 가능한지

        // 0과 1 입력
        for (int i = 0; i < N; i++) {
            String s = br.readLine();
            for (int j = 0; j < N; j++) {
                char c = s.charAt(j);
                arr[i][j] = c == '1' ? '1' : '0';
                if (c == 'B') {
                    listB.add(new int[]{i, j}); // 통나무 좌표
                }
                if (c == 'E') {
                    listE.add(new int[]{i, j}); // 목적지 좌표
                }
            }
        }
        // 가로, 세로 확인 (좌표들의 가로방향 좌표가 같으면 0 (가로), 아니면 1(세로) )
        listB.add(new int[]{listB.get(0)[0] == listB.get(1)[0] ? 0 : 1, 0, 0}); // 가로세로, 움직임, 회전 횟수
        listE.add(new int[]{listE.get(0)[0] == listE.get(1)[0] ? 0 : 1});

        Queue<ArrayList<int[]>> q = new LinkedList<>();
        q.add(listB);
        visited[listB.get(1)[0]][listB.get(1)[1]][listB.get(3)[0]] = true;

        while (!q.isEmpty()) {
            ArrayList<int[]> list = q.poll();

            // 가운데 좌표랑 가로세로 맞는지 확인해서 같으면 중단
            if (listE.get(1)[0] == list.get(1)[0]
                    && listE.get(1)[1] == list.get(1)[1]
                    && listE.get(3)[0] == list.get(3)[0]) {
                answer = list.get(3)[1];
                break;
            }

            // 움직임
            outer:
            for (int i = 0; i < d.length; i++) {
                ArrayList<int[]> temp = new ArrayList<>();

                // 리스트 복사
                for (int j = 0; j < 4; j++) {
                    // 리스트 마지막이 원소 갯수 많음
                    if (j == 3) {
                        temp.add(new int[]{list.get(j)[0], list.get(j)[1], list.get(j)[2]});
                    } else {
                        temp.add(new int[]{list.get(j)[0], list.get(j)[1]});
                    }
                }

                // 이동
                for (int j = 0; j < 3; j++) {
                    // 회전 횟수 비교해서 처리
                    temp.get(j)[0] += list.get(3)[2] % 2 == 1 ? d[i][j][0] : d[i][2 - j][0];
                    temp.get(j)[1] += list.get(3)[2] % 2 == 1 ? d[i][j][1] : d[i][2 - j][1];
                    // 1에 걸리거나 벗어나면 continue
                    if (temp.get(j)[0] < 0 || temp.get(j)[0] >= N
                            || temp.get(j)[1] < 0 || temp.get(j)[1] >= N || arr[temp.get(j)[0]][temp.get(j)[1]] == '1') {
                        continue outer;
                    }
                }

                // 회전 하는 경우
                if (i == d.length - 1) {
                    temp.get(3)[0] = (temp.get(3)[0] + 1) % 2;  // 가로 세로 방향 전환
                    temp.get(3)[2]++;   // 회전 횟수 +1
                    // 회전 하는 경로에 1에 걸리면 continue
                    for (int j = 0; j < 4; j++) {
                        if (arr[temp.get(1)[0] + rotation[j][0]][temp.get(1)[1] + rotation[j][1]] == '1') {
                            continue outer;
                        }
                    }
                }

                // 이동한 가운데 좌표와 가로, 세로에 맞게 방문 한지 확인
                if (!visited[temp.get(1)[0]][temp.get(1)[1]][temp.get(3)[0]]) {
                    visited[temp.get(1)[0]][temp.get(1)[1]][temp.get(3)[0]] = true;
                    temp.get(3)[1]++;   // 이동 횟수 +1
                    q.add(temp);
                }
            }
        }
        System.out.println(answer);

    }
}

'코딩테스트 > [백준] 코딩테스트 연습' 카테고리의 다른 글

가스관 - 2931번  (0) 2022.03.13
구슬 탈출2 - 13460번  (0) 2022.03.10
2048 (Easy) - 12100번  (0) 2022.03.07
연구소 - 14502번  (0) 2022.03.04
동작 그만. 밑장 빼기냐? - 20519번  (0) 2022.03.02
    '코딩테스트/[백준] 코딩테스트 연습' 카테고리의 다른 글
    • 가스관 - 2931번
    • 구슬 탈출2 - 13460번
    • 2048 (Easy) - 12100번
    • 연구소 - 14502번
    쵼쥬
    쵼쥬

    티스토리툴바