-
백준 3055, 1600, 7576Java/코딩테스트 2023. 8. 30. 02:54
이번에 문제를 풀 때는 Pos class 따로 만들지 않고 배열로 만들어서도 풀어봤다.
스터디원들이 내 준 문제들이 어째 다 골드여서.. 열심히 풀었다는 tmi...
백준 3055 탈출 🦔
https://www.acmicpc.net/problem/3055
3055번: 탈출
사악한 암흑의 군주 이민혁은 드디어 마법 구슬을 손에 넣었고, 그 능력을 실험해보기 위해 근처의 티떱숲에 홍수를 일으키려고 한다. 이 숲에는 고슴도치가 한 마리 살고 있다. 고슴도치는 제
www.acmicpc.net
🦔 바보같이 S가 비버의 굴...인줄 알고 풀었다. 답이 계속 이상하길래 헤맸다...ㅋㅋ
🦔 물 먼저 퍼트리고, 그 다음 고슴도치를 이동시킨다. 원래 각각에 해당하는 temp 리스트를 만들까 했는데, 메모리가 옹졸하다. 그래서 계속 물 / 고슴도치 BFS 돌리기 전에 size 구한 다음, 그 만큼만 돌리는 방식으로 구현하였다.
🦔 고슴도치가 갈 수 있는 공간이 남아있을 때까지 반복 / 더 이상 이동할 수 없다면 while문 반복을 종료하고 나온다.
🦔 이 버전을 각각 Pos, Animal class 구현해서 제출 해봤는데, 메모리를 조금 더 쓰고 시간을 아낄수 있었다.
import java.util.*; import java.io.*; public class p3055 { private static int row, col; private static char[][] map; private static int[] dirX = { -1, 1, 0, 0 }; private static int[] dirY = { 0, 0, -1, 1 }; private static Queue<int[]> waterPos; private static Queue<int[]> animalPos; private static int answer; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); row = Integer.parseInt(st.nextToken()); col = Integer.parseInt(st.nextToken()); waterPos = new LinkedList<>(); animalPos = new LinkedList<>(); map = new char[row][col]; answer = Integer.MAX_VALUE; for (int i = 0; i < row; i++) { String str = br.readLine(); for (int j = 0; j < col; j++) { map[i][j] = str.charAt(j); if (map[i][j] == 'S') { animalPos.add(new int[]{i, j, 0}); } else if (map[i][j] == '*') { waterPos.add(new int[] { i, j }); } } } BFS(); if (answer == Integer.MAX_VALUE) { System.out.println("KAKTUS"); } else { System.out.println(answer); } } private static void BFS() { while (!animalPos.isEmpty()) { int size = waterPos.size(); for (int w = 0; w < size; w++) { int[] waterPoll = waterPos.poll(); for (int i = 0; i < 4; i++) { int nextX = waterPoll[0] + dirX[i]; int nextY = waterPoll[1] + dirY[i]; if (isValid(nextX, nextY)) { if (map[nextX][nextY] == '.' || map[nextX][nextY] == 'S') { map[nextX][nextY] = '*'; waterPos.add(new int[] {nextX, nextY}); } } } } // 고슴도치 size = animalPos.size(); for (int m = 0; m < size; m++) { int[] poll = animalPos.poll(); for (int i = 0; i < 4; i++) { int nextX = poll[0] + dirX[i]; int nextY = poll[1] + dirY[i]; if (isValid(nextX, nextY)) { if (map[nextX][nextY] == 'D') { answer = Math.min(answer, poll[2] + 1); return; } else if (map[nextX][nextY] == '.') { map[nextX][nextY] = 'S'; animalPos.add(new int[] {nextX, nextY, poll[2] + 1}); } } } } } } private static boolean isValid(int x, int y) { if (x < 0 || x >= row || y < 0 || y >= col) { return false; } return true; } }
백준 1600 말이 되고픈 원숭이 🐵
https://www.acmicpc.net/problem/1600
1600번: 말이 되고픈 원숭이
첫째 줄에 정수 K가 주어진다. 둘째 줄에 격자판의 가로길이 W, 세로길이 H가 주어진다. 그 다음 H줄에 걸쳐 W개의 숫자가 주어지는데, 0은 아무것도 없는 평지, 1은 장애물을 뜻한다. 장애물이 있
www.acmicpc.net
🐵 말처럼 행동할 수 있는 경우가 K번으로 제한이 있는 점이 이전에 푼 백준 14442 - 벽 뚫고 가기랑 비슷하다.
🐵 상하좌우 움직임 + 말이 움직일 수 있는 8가지도 미리 정의를 해 두었다.
🐵 말처럼 행동 가능한 횟수를 안 넘겼다면 말 처럼 행동하는 반경에도 방문 처리하기
🐵 방문 배열은 몇 번 말처럼 행동해서 온 건지 정보도 담아야 해서 3차원 배열로 선언해두었다.
import java.io.*; import java.util.*; public class p1600 { private static int k, row, col, answer; private static int[][][] visit; private static int[][] map; private static int[] dirX = { -1, 1, 0, 0 }; private static int[] dirY = { 0, 0, -1, 1 }; private static int[] horseX = { -2, -2, -1, 1, 2, 2, 1, -1 }; private static int[] horseY = { -1, 1, 2, 2, 1, -1, -2, -2 }; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); k = Integer.parseInt(br.readLine()); StringTokenizer st = new StringTokenizer(br.readLine()); col = Integer.parseInt(st.nextToken()); row = Integer.parseInt(st.nextToken()); map = new int[row][col]; visit = new int[row][col][k+1]; answer = -1; for (int i = 0; i < row; i++) { st = new StringTokenizer(br.readLine()); for (int j = 0; j < col; j++) { map[i][j] = Integer.parseInt(st.nextToken()); } } BFS(); System.out.println(answer); } private static void BFS() { Queue<Pos> queue = new LinkedList<>(); queue.add(new Pos(0, 0, 0)); visit[0][0][0] = 1; while (!queue.isEmpty()) { Pos poll = queue.poll(); if (poll.x == row-1 && poll.y == col-1) { int temp = Integer.MAX_VALUE; for (int i = 0; i <= k; i++) { if (visit[row-1][col-1][i] != 0) { temp = Math.min(temp, visit[row-1][col-1][i]-1); } } if (temp != Integer.MAX_VALUE) { answer = temp; } break; } for (int i = 0; i < 4; i++) { int nextX = poll.x + dirX[i]; int nextY = poll.y + dirY[i]; if (isValid(nextX, nextY)) { if (map[nextX][nextY] == 1) { continue; } if (visit[nextX][nextY][poll.horseMove] == 0) { visit[nextX][nextY][poll.horseMove] = visit[poll.x][poll.y][poll.horseMove] + 1; queue.add(new Pos(nextX, nextY, poll.horseMove)); } } } if (poll.horseMove < k) { for (int i = 0; i < 8; i++) { int nextX = poll.x + horseX[i]; int nextY = poll.y + horseY[i]; if (isValid(nextX, nextY)) { if (map[nextX][nextY] == 1) { continue; } if (visit[nextX][nextY][poll.horseMove + 1] == 0) { visit[nextX][nextY][poll.horseMove + 1] = visit[poll.x][poll.y][poll.horseMove] + 1; queue.add(new Pos(nextX, nextY, poll.horseMove+1)); } } } } } } private static boolean isValid(int x, int y) { if (x < 0 || x >= row || y < 0 || y >= col) { return false; } return true; } private static class Pos { int x; int y; int horseMove; public Pos(int x, int y, int horseMove) { this.x = x; this.y = y; this.horseMove = horseMove; } } }
백준 7576 토마토 🍅
https://www.acmicpc.net/problem/7576
7576번: 토마토
첫 줄에는 상자의 크기를 나타내는 두 정수 M,N이 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M,N ≤ 1,000 이다. 둘째 줄부터는 하나의 상자에 저장된 토마토
www.acmicpc.net
🍅 전형적인 BFS 문제
🍅 처음부터 토마토가 모두 익은 상태로 주어지는 경우도 있으므로 안 익은 토마토 개수만 먼저 세고, 0일 경우 BFS 수행하지 말기
🍅 익어있는 토마토만 reds 리스트에 담아두었다가 BFS수행 시 큐에 다 넣고 거기서부터 BFS 시작하기
🍅 마지막에 결과 출력시에 -1을 해줘야 한다. 처음 익어있는 토마토를 1로 두고 시작했기 때문에 마지막에 -1하기.
import java.util.*; import java.io.*; public class p7576 { private static int row, col, all; private static List<int[]> reds; private static int[][] tomato; private static int[] dirX = { -1, 1, 0, 0 }; private static int[] dirY = { 0, 0, -1, 1 }; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); col = Integer.parseInt(st.nextToken()); row = Integer.parseInt(st.nextToken()); all = 0; tomato = new int[row][col]; reds = new ArrayList<>(); for (int i = 0; i < row; i++) { st = new StringTokenizer(br.readLine()); for (int j = 0; j < col; j++) { tomato[i][j] = Integer.parseInt(st.nextToken()); if (tomato[i][j] == 1) { reds.add(new int[] {i, j}); } else if (tomato[i][j] == 0) { all++; } } } if (all == 0) { System.out.println(0); return; } BFS(); if (all == 0) { System.out.println(count()-1); } else { System.out.println(-1); } } private static int count() { int answer = Integer.MIN_VALUE; for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (tomato[i][j] > answer) { answer = tomato[i][j]; } } } return answer; } private static void BFS() { Queue<int[]> queue = new LinkedList<>(reds); while (!queue.isEmpty()) { int[] poll = queue.poll(); for (int i = 0; i < 4; i++) { int nextX = poll[0] + dirX[i]; int nextY = poll[1] + dirY[i]; if (!isValid(nextX, nextY)) { continue; } if (tomato[nextX][nextY] == 0) { tomato[nextX][nextY] = tomato[poll[0]][poll[1]] + 1; all--; queue.add(new int[] {nextX, nextY}); } } } } private static boolean isValid(int x, int y) { if (x < 0 || x >= row || y < 0 || y >= col) { return false; } return true; } }
'Java > 코딩테스트' 카테고리의 다른 글
프로그래머스 시험장 나누기, 백준 21610 (0) 2023.09.19 백준 2636, 1339, 2110 (0) 2023.09.05 백준 2140, 28303, 2258 (0) 2023.08.22 백준 2240 (0) 2023.08.15 백준 2293 (0) 2023.08.15