diff --git a/README.md b/README.md
index 78e5a43..2af1f23 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,143 @@
***
+## 2022 06/16 ~ 06/20
+| 난이도 | 문제 번호 | 문제 이름 | 분류 |
+|:------:|:----:|:---------:|:-----:|
+|
| [2212](https://www.acmicpc.net/problem/2212) | [센서](https://www.acmicpc.net/problem/2212) | Blind |
+|
| [11509](https://www.acmicpc.net/problem/11509) | [풍선 맞추기](https://www.acmicpc.net/problem/11509) | Blind |
+|
| [14722](https://www.acmicpc.net/problem/14722) | [우유 도시](https://www.acmicpc.net/problem/14722) | Blind |
+
+
+
+
+
+
+## 2022 06/09 ~ 06/13
+| 난이도 | 문제 번호 | 문제 이름 | 분류 |
+|:------:|:----:|:---------:|:-----:|
+|  | [2020 KAKAO BLIND RECRUITMENT](https://programmers.co.kr/learn/courses/30/lessons/60062) | [외벽 점검](https://programmers.co.kr/learn/courses/30/lessons/60062) | Blind |
+|
| [5569](https://www.acmicpc.net/problem/5569) | [출근 경로](https://www.acmicpc.net/problem/5569) | Blind |
+|
| [16927](https://www.acmicpc.net/problem/16927) | [배열 돌리기 2](https://www.acmicpc.net/problem/16927) | Blind |
+
+
+
+
+
+
+## 2022 06/02 ~ 06/06
+| 난이도 | 문제 번호 | 문제 이름 | 분류 |
+|:------:|:----:|:---------:|:-----:|
+|
| [1780](https://www.acmicpc.net/problem/1780) | [종이의 개수](https://www.acmicpc.net/problem/1780) | Blind |
+|
| [1253](https://www.acmicpc.net/problem/1253) | [좋다](https://www.acmicpc.net/problem/1253) | Blind |
+|
| [17090](https://www.acmicpc.net/problem/17090) | [미로 탈출하기](https://www.acmicpc.net/problem/17090) | Blind |
+
+
+
+
+
+
+## 2022 05/26 ~ 05/30
+| 난이도 | 문제 번호 | 문제 이름 | 분류 |
+|:------:|:----:|:---------:|:-----:|
+|
| [4781](https://www.acmicpc.net/problem/4781) | [사탕가게](https://www.acmicpc.net/problem/4781) | DP |
+|
| [2234](https://www.acmicpc.net/problem/2234) | [성곽](https://www.acmicpc.net/problem/2234) | 비트마스킹 |
+|
| [14719](https://www.acmicpc.net/problem/14719) | [빗물](https://www.acmicpc.net/problem/14719) | 구현 |
+
+
+
+
+
+
+## 2022 05/23 ~ 05/26
+| 난이도 | 문제 번호 | 문제 이름 | 분류 |
+|:------:|:----:|:---------:|:-----:|
+|
| [5557](https://www.acmicpc.net/problem/5557) | [1학년](https://www.acmicpc.net/problem/5557) | Blind |
+|
| [20056](https://www.acmicpc.net/problem/20056) | [마법사 상어와 파이어볼](https://www.acmicpc.net/problem/20056) | 구현 |
+|
| [1162](https://www.acmicpc.net/problem/1162) | [도로포장](https://www.acmicpc.net/problem/1162) | Blind |
+
+
+
+
+
+
+
+## 2022 05/20 ~ 05/23
+| 난이도 | 문제 번호 | 문제 이름 | 분류 |
+|:------:|:----:|:---------:|:-----:|
+|
| [20055](https://www.acmicpc.net/problem/20055) | [컨베이어 벨트 위의 로봇](https://www.acmicpc.net/problem/20055) | 구현 |
+|
| [15683](https://www.acmicpc.net/problem/15683) | [감시](https://www.acmicpc.net/problem/15683) | 구현 |
+
+
+
+
+
+
+## 2022 05/16 ~ 05/19
+| 난이도 | 문제 번호 | 문제 이름 | 분류 |
+|:------:|:----:|:---------:|:-----:|
+|
| [22352](https://www.acmicpc.net/problem/22352) | [항체 인식](https://www.acmicpc.net/problem/22352) | Blind |
+|
| [2573](https://www.acmicpc.net/problem/2573) | [빙산](https://www.acmicpc.net/problem/2573) | Blind |
+|
| [1963](https://www.acmicpc.net/problem/1963) | [소수 경로](https://www.acmicpc.net/problem/1963) | Blind |
+
+
+
+
+
+
+
+## 2022 05/12 ~ 05/16
+| 난이도 | 문제 번호 | 문제 이름 | 분류 |
+|:------:|:----:|:---------:|:-----:|
+|
| [1654](https://www.acmicpc.net/problem/1654) | [랜선 자르기](https://www.acmicpc.net/problem/1654) | [파라메트릭 서치](https://solved.ac/problems/tags/parametric_search) |
+|
| [17471](https://www.acmicpc.net/problem/17471) | [게리맨더링](https://www.acmicpc.net/problem/17471) | Blind |
+|
| [21609](https://www.acmicpc.net/problem/21609) | [상어 중학교](https://www.acmicpc.net/problem/21609) | Blind |
+
+
+
+
+
+
+
+## 2022 05/09 ~ 05/12
+| 난이도 | 문제 번호 | 문제 이름 | 분류 |
+|:------:|:----:|:---------:|:-----:|
+|
| [14630](https://www.acmicpc.net/problem/14630) | [변신로봇](https://www.acmicpc.net/problem/14630) | [다익스트라](https://solved.ac/problems/tags/dijkstra) |
+|
| [1922](https://www.acmicpc.net/problem/1922) | [네트워크 연결](https://www.acmicpc.net/problem/1922) | [최소 스패닝 트리](https://solved.ac/problems/tags/mst?sort=level&direction=asc&page=1) |
+|
| [3151](https://www.acmicpc.net/problem/3151) | [합이 0](https://www.acmicpc.net/problem/3151) | [투포인터](https://solved.ac/problems/tags/two_pointer) |
+
+
+
+
+
+
+## 2022 05/05
+### 2022 카카오 인턴십 대비 모의 코딩테스트
+* 시험 시간 : 14:00 ~ 17:00 (총 3시간)
+
+| 난이도 | 문제 번호 | 문제 이름 | 분류 |
+|:------:|:----:|:---------:|:-----:|
+| Blind | [프로그래머스](https://programmers.co.kr/learn/challenges) | [오픈채팅방](https://programmers.co.kr/learn/courses/30/lessons/42888) | Blind |
+| Blind | [프로그래머스](https://programmers.co.kr/learn/challenges) | [기둥과 보 설치](https://programmers.co.kr/learn/courses/30/lessons/60061) | Blind |
+| Blind | [프로그래머스](https://programmers.co.kr/learn/challenges) | [블록이동하기](https://programmers.co.kr/learn/courses/30/lessons/60063) | Blind |
+
+
+
+
+
+
+## 2022 04/28 ~ 05/02
+| 난이도 | 문제 번호 | 문제 이름 | 분류 |
+|:------:|:----:|:---------:|:-----:|
+|  | [2022 KAKAO 공채](https://programmers.co.kr/learn/challenges) | [사라지는 발판](https://programmers.co.kr/learn/courses/30/lessons/92345) | Blind |
+|  | [2021 KAKAO 공채](https://programmers.co.kr/learn/challenges) | [합승 택시 요금](https://programmers.co.kr/learn/courses/30/lessons/72413) | Blind |
+|  | [2021 KAKAO 공채](https://programmers.co.kr/learn/challenges) | [카드 짝 맞추기](https://programmers.co.kr/learn/courses/30/lessons/72415) | Blind |
+
+
+
+
+
+
## 2022 04/25 ~ 04/28
| 난이도 | 문제 번호 | 문제 이름 | 분류 |
|:------:|:----:|:---------:|:-----:|
diff --git a/choiyoungkwon12/week17/Solution72413.java b/choiyoungkwon12/week17/Solution72413.java
new file mode 100644
index 0000000..e836475
--- /dev/null
+++ b/choiyoungkwon12/week17/Solution72413.java
@@ -0,0 +1,50 @@
+package Programmers;
+
+/**
+ * https://programmers.co.kr/learn/courses/30/lessons/72413 합승 택시 요금
+ */
+public class Solution72413 {
+
+ public static void main(String[] args) {
+ Solution72413 s = new Solution72413();
+ int solution = s.solution(6, 4, 6, 2,
+ new int[][]{{4, 1, 10}, {3, 5, 24}, {5, 6, 2}, {3, 1, 41}, {5, 1, 24}, {4, 6, 50}, {2, 4, 66}, {2, 3, 22},
+ {1, 6, 25}});
+
+ System.out.println(solution);
+ }
+
+ public int solution(int n, int s, int a, int b, int[][] fares) {
+ int[][] node = new int[n + 1][n + 1];
+
+ for (int i = 1; i < n + 1; i++) {
+ for (int j = 1; j < n + 1; j++) {
+ node[i][j] = 20000001;
+ }
+ node[i][i] = 0;
+ }
+
+ for (int[] fare : fares) {
+ node[fare[0]][fare[1]] = fare[2];
+ node[fare[1]][fare[0]] = fare[2];
+ }
+
+ for (int k = 1; k < n + 1; k++) {
+ for (int i = 1; i < n + 1; i++) {
+ for (int j = 1; j < n + 1; j++) {
+ if (node[i][j] > node[i][k] + node[k][j]) {
+ node[i][j] = node[i][k] + node[k][j];
+ }
+ }
+ }
+ }
+
+ int min = Integer.MAX_VALUE;
+
+ for(int i = 1; i < n + 1; i++) {
+ min = Math.min(min, node[s][i] + node[i][a] + node[i][b]);
+ }
+
+ return min;
+ }
+}
diff --git a/choiyoungkwon12/week17/Solution72415.java b/choiyoungkwon12/week17/Solution72415.java
new file mode 100644
index 0000000..09c0211
--- /dev/null
+++ b/choiyoungkwon12/week17/Solution72415.java
@@ -0,0 +1,172 @@
+package Programmers;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+/**
+ * https://programmers.co.kr/learn/courses/30/lessons/72415 카드 짝 맞추기
+ */
+public class Solution72415 {
+
+ static List orders;
+ static int[] dx = {0, 0, 1, -1};
+ static int[] dy = {1, -1, 0, 0};
+
+ public static void main(String[] args) {
+ Solution72415 s = new Solution72415();
+ int solution = s.solution(new int[][]{{1, 0, 0, 3}, {2, 0, 0, 0}, {0, 0, 0, 2}, {3, 0, 1, 0}}, 1, 0);
+ System.out.println(solution);
+ }
+
+ public int solution(int[][] board, int r, int c) {
+ int cardNum = 0;
+
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ if (board[i][j] != 0) {
+ cardNum++;
+ }
+ }
+ }
+
+ cardNum /= 2;
+
+ int[] card = new int[cardNum];
+ for (int i = 0; i < cardNum; i++) {
+ card[i] = i + 1;
+ }
+
+ orders = new ArrayList<>();
+ permutation("", 0, card);
+
+ int min = Integer.MAX_VALUE;
+ for (String comb : orders) {
+ String[] order = comb.split("");
+
+ int totalMove = 0;
+ int[] pos = new int[2];
+ pos[0] = r;
+ pos[1] = c;
+
+ int[][] copyBoard = new int[4][4];
+ for (int i = 0; i < 4; i++) {
+ System.arraycopy(board[i], 0, copyBoard[i], 0, 4);
+ }
+ for (String target : order) {
+ int cardNumber = Integer.parseInt(target);
+
+ totalMove += cardSearch(pos, cardNumber, copyBoard);
+ copyBoard[pos[0]][pos[1]] = 0;
+
+ totalMove += 1;
+
+ totalMove += cardSearch(pos, cardNumber, copyBoard);
+ copyBoard[pos[0]][pos[1]] = 0;
+
+ totalMove += 1;
+ }
+
+ min = Math.min(min, totalMove);
+ }
+
+ return min;
+ }
+
+ private int cardSearch(int[] pos, int targetCard, int[][] copyBoard) {
+ Queue q = new LinkedList<>();
+ boolean[][] check = new boolean[4][4];
+ int x = pos[0];
+ int y = pos[1];
+
+ check[x][y] = true;
+ q.add(new Pair(x, y, 0));
+ while (!q.isEmpty()) {
+ Pair next = q.poll();
+ int px = next.x;
+ int py = next.y;
+ int move = next.move;
+
+ if (copyBoard[px][py] == targetCard) {
+ // System.out.println("[" + targetCard + "] find! " + next.x + "," + next.y + ":" + move);
+ pos[0] = next.x;
+ pos[1] = next.y;
+ return move;
+ }
+
+ for (int i = 0; i < 4; i++) {
+ int nx = px + dx[i];
+ int ny = py + dy[i];
+
+ if (nx < 0 || ny < 0 || nx > 3 || ny > 3) {
+ continue;
+ }
+ if (check[nx][ny]) {
+ continue;
+ }
+ check[nx][ny] = true;
+ q.add(new Pair(nx, ny, move + 1));
+ }
+
+ for (int i = 0; i < 4; i++) {
+ Pair res = checkRoute(px, py, i, copyBoard);
+ int nx = res.x;
+ int ny = res.y;
+
+ if (nx == x && ny == y) {
+ continue;
+ }
+ if (check[nx][ny]) {
+ continue;
+ }
+
+ check[nx][ny] = true;
+ q.add(new Pair(nx, ny, move + 1));
+ }
+ }
+
+ return 0;
+ }
+
+ private Pair checkRoute(int x, int y, int direction, int[][] copyBoard) {
+ x += dx[direction];
+ y += dy[direction];
+
+ while (x >= 0 && x < 4 && y >= 0 && y < 4) {
+ if (copyBoard[x][y] != 0) {
+ return new Pair(x, y, 0);
+ }
+
+ x += dx[direction];
+ y += dy[direction];
+ }
+
+ return new Pair(x - dx[direction], y - dy[direction], 0);
+ }
+
+ private void permutation(String comb, int depth, int[] card) {
+ if (card.length == depth) {
+ orders.add(comb);
+ return;
+ }
+ for (int num : card) {
+ if (!comb.contains("" + num)) {
+ permutation(comb + num, depth + 1, card);
+ }
+ }
+ }
+
+ static class Pair {
+
+ int x;
+ int y;
+ int move;
+
+ public Pair(int x, int y, int move) {
+ this.x = x;
+ this.y = y;
+ this.move = move;
+ }
+ }
+}
diff --git a/choiyoungkwon12/week17/Solution92345.java b/choiyoungkwon12/week17/Solution92345.java
new file mode 100644
index 0000000..98f45f3
--- /dev/null
+++ b/choiyoungkwon12/week17/Solution92345.java
@@ -0,0 +1,79 @@
+package Programmers;
+
+/**
+ * https://programmers.co.kr/learn/courses/30/lessons/92345 사라지는 발판
+ */
+public class Solution92345 {
+
+ int[] dx = {0, 0, 1, -1};
+ int[] dy = {-1, 1, 0, 0};
+
+ int n, m;
+
+ boolean[][] visit = new boolean[5][5];
+ int[][] block = new int[5][5];
+
+ public static void main(String[] args) {
+ Solution92345 s = new Solution92345();
+ int solution = s.solution(new int[][]{{1, 1, 1, 1, 1}}, new int[]{0, 0}, new int[]{0, 4});
+ System.out.println(solution);
+ }
+
+ // 현재 상태에서 둘 다 최적의 플레이를 할 때 남은 이동 횟수
+ // 반환 값이 짝수 : 플레이어가 패배함을 의미, 홀수 : 플레이어가 승리함을 의미
+ // curx, cury : 현재 플레이어의 좌표, opx, opy : 상대 플레이어의 좌표
+ public int solve(int curx, int cury, int opx, int opy) {
+ // 플레이어가 밟고 있는 발판이 사라졌다면
+ if (visit[curx][cury]) {
+ return 0;
+ }
+ int ret = 0;
+
+ // 플레이어를 네 방향으로 이동시켜 다음 단계로 진행할 예정
+ for (int dir = 0; dir < 4; dir++) {
+ int nx = curx + dx[dir];
+ int ny = cury + dy[dir];
+ if (OOB(nx, ny) || visit[nx][ny] || block[nx][ny] == 0) {
+ continue;
+ }
+ visit[curx][cury] = true; // 플레이어가 직전에 있던 곳은 방문 표시를 함.
+
+ //플레이어를 dir 방향으로 이동 시켰을 때 턴의 수
+ // 다음 함수를 호출할 때 opx, opy, nx, ny 순으로 호출
+ int val = solve(opx, opy, nx, ny) + 1;
+
+ // 방문 표시 해제
+ visit[curx][cury] = false;
+
+ // 1. 현재 저장된 턴은 패배인데 새로 계산된 턴은 승리인 경우
+ if (ret % 2 == 0 && val % 2 == 1) {
+ ret = val; // 바로 갱신
+
+ // 현재 저장된 턴과 새로 계산된 턴이 모두 패배인 경우
+ } else if (ret % 2 == 0 && val % 2 == 0) {
+ ret = Math.max(ret, val); // 최대한 늦게 지는 것을 선택
+
+ // 현재 저장된 턴과 새로 저장된 턴이 모두 승리인 경우
+ } else if (ret % 2 == 1 && val % 2 == 1) {
+ ret = Math.min(ret, val); // 최대한 빠르게 이기는 것을 선택
+ }
+ }
+
+ return ret;
+ }
+
+ public boolean OOB(int x, int y) {
+ return x < 0 || x >= n || y < 0 || y >= m;
+ }
+
+ public int solution(int[][] board, int[] aloc, int[] bloc) {
+ n = board.length;
+ m = board[0].length;
+ for (int i = 0; i < n; i++) {
+ if (m >= 0) {
+ System.arraycopy(board[i], 0, block[i], 0, m);
+ }
+ }
+ return solve(aloc[0], aloc[1], bloc[0], bloc[1]);
+ }
+}
diff --git a/eonju/BOJ/BOJ_1253.java b/eonju/BOJ/BOJ_1253.java
new file mode 100644
index 0000000..e55644f
--- /dev/null
+++ b/eonju/BOJ/BOJ_1253.java
@@ -0,0 +1,56 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+
+class Main {
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
+ int n = Integer.parseInt(bufferedReader.readLine());
+ int[] numbers = Arrays.stream(bufferedReader.readLine().split(" "))
+ .mapToInt(Integer::parseInt)
+ .sorted()
+ .toArray();
+
+ if (numbers.length < 3) {
+ System.out.println(0);
+ return;
+ }
+
+ int answer = 0;
+
+ for (int i = 2; i < n; i++) {
+ int target = numbers[i];
+ int left = 0;
+ int right = i - 1;
+
+ while (left < right) {
+ if (left == i) {
+ left++;
+ continue;
+ }
+
+ if (right == i) {
+ right--;
+ continue;
+ }
+ if (target == numbers[left] + numbers[right]) {
+ answer++;
+ break;
+ }
+
+ if (target > numbers[left] + numbers[right]) {
+ left++;
+ continue;
+ }
+
+ if (target < numbers[left] + numbers[right]) {
+ right--;
+ }
+ }
+ }
+
+ System.out.println(answer);
+ }
+}
diff --git a/eonju/BOJ/BOJ_14630.java b/eonju/BOJ/BOJ_14630.java
new file mode 100644
index 0000000..c511384
--- /dev/null
+++ b/eonju/BOJ/BOJ_14630.java
@@ -0,0 +1,102 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.PriorityQueue;
+
+public class Main {
+
+ private static HashMap> graph;
+ private static int[] dist;
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
+ int n = Integer.parseInt(bufferedReader.readLine());
+
+ graph = new HashMap<>();
+
+ String[] types = new String[n + 1];
+ for (int i = 1; i <= n; i++) {
+ String input = bufferedReader.readLine();
+ types[i] = input;
+ graph.put(i, new ArrayList<>());
+ }
+
+ String[] inputs = bufferedReader.readLine().split(" ");
+ int start = Integer.parseInt(inputs[0]);
+ int end = Integer.parseInt(inputs[1]);
+
+ makeGraph(types);
+
+ dist = new int[n + 1];
+ dijkstra(start);
+
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < types[start].length(); i++) {
+ sb.append("0");
+ }
+ int weight = getWeight(types[start], sb.toString());
+
+ System.out.println(Math.min(dist[end], weight);
+ }
+
+ public static void dijkstra(int start) {
+ Arrays.fill(dist, Integer.MAX_VALUE);
+ dist[start] = 0;
+
+ PriorityQueue queue = new PriorityQueue<>(Comparator.comparing(x -> x.weight));
+ queue.add(new Node(start, 0));
+
+ while (!queue.isEmpty()) {
+ Node poll = queue.poll();
+
+ if (poll.weight > dist[poll.end]) {
+ continue;
+ }
+
+ for (Node node : graph.get(poll.end)) {
+ if (dist[node.end] > poll.weight + node.weight) {
+ dist[node.end] = poll.weight + node.weight;
+ queue.add(new Node(node.end, dist[node.end]));
+ }
+ }
+ }
+ }
+
+ public static void makeGraph(String[] types) {
+ for (int i = 1; i < types.length - 1; i++) {
+ for (int j = i + 1; j < types.length; j++) {
+ int weight = getWeight(types[i], types[j]);
+ graph.get(i).add(new Node(j, weight));
+ graph.get(j).add(new Node(i, weight));
+ }
+ }
+ }
+
+ public static int getWeight(String numberA, String numberB) {
+ String[] splitA = numberA.split("");
+ String[] splitB = numberB.split("");
+
+ int weight = 0;
+ for (int i = 0; i < splitA.length; i++) {
+ weight += Math.pow(Math.abs(Integer.parseInt(splitA[i]) - Integer.parseInt(splitB[i])), 2);
+ }
+
+ return weight;
+ }
+
+ static class Node {
+
+ int end;
+ int weight;
+
+ public Node(int end, int weight) {
+ this.end = end;
+ this.weight = weight;
+ }
+ }
+}
diff --git a/eonju/BOJ/BOJ_14719.java b/eonju/BOJ/BOJ_14719.java
new file mode 100644
index 0000000..e83262a
--- /dev/null
+++ b/eonju/BOJ/BOJ_14719.java
@@ -0,0 +1,67 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+class Main {
+
+ private static boolean[][] map;
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
+ String[] input = bufferedReader.readLine().split(" ");
+ int height = Integer.parseInt(input[0]);
+ int width = Integer.parseInt(input[1]);
+
+ map = new boolean[width][height];
+
+ input = bufferedReader.readLine().split(" ");
+ for (int i = 0; i < input.length; i++) {
+ fillMap(i, Integer.parseInt(input[i]));
+ }
+
+ int answer = count(width, height);
+ System.out.println(answer);
+ }
+
+ public static void fillMap(int idx, int height) {
+ for (int i = 0; i < height; i++) {
+ map[idx][i] = true;
+ }
+ }
+
+ public static int count(int height, int width) {
+ int cnt = 0;
+
+ for (int i = 0; i < width; i++) {
+ int left = -1;
+ int right = -1;
+ int tmp = 0;
+
+ for (int j = 0; j < height; j++) {
+ if (map[j][i] && left == -1) {
+ left = j;
+ continue;
+ }
+ if (map[j][i] && left != -1 && right == -1) {
+ cnt += tmp;
+ tmp = 0;
+ right = j;
+ continue;
+ }
+ if (map[j][i] && left != -1 && right != -1) {
+ cnt += tmp;
+ tmp = 0;
+ left = right;
+ right = j;
+ continue;
+ }
+ if (!map[j][i] && left != -1) {
+ tmp++;
+ }
+ }
+ }
+
+ return cnt;
+ }
+
+}
diff --git a/eonju/BOJ/BOJ_15683.java b/eonju/BOJ/BOJ_15683.java
new file mode 100644
index 0000000..b4b7062
--- /dev/null
+++ b/eonju/BOJ/BOJ_15683.java
@@ -0,0 +1,113 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.StringTokenizer;
+
+class Main {
+ private static final int[][] move = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // 0위, 1아래, 2왼쪽, 3오른쪽
+ private static final int BLANK = 0;
+ private static final int WALL = 6;
+
+ private static int[][] ONE = {{0}, {1}, {2}, {3}};
+ private static int[][] TWO = {{0, 1}, {2, 3}};
+ private static int[][] THREE = {{0, 2}, {0, 3}, {1, 2}, {1, 3}};
+ private static int[][] FOUR = {{0, 2, 3}, {0, 1, 2}, {1, 2, 3}, {0, 1, 3}};
+ private static int[][] FIVE = {{0, 1, 2, 3}};
+ private static int[][] map;
+
+ private static int answer = Integer.MAX_VALUE;
+ private static ArrayList cameras;
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
+ StringTokenizer st = new StringTokenizer(bufferedReader.readLine());
+
+ int height = Integer.parseInt(st.nextToken());
+ int width = Integer.parseInt(st.nextToken());
+
+ map = new int[height][width];
+ cameras = new ArrayList<>();
+ int[][] visited = new int[height][width];
+
+ for (int i = 0; i < height; i++) {
+ st = new StringTokenizer(bufferedReader.readLine());
+ for (int j = 0; j < width; j++) {
+ map[i][j] = Integer.parseInt(st.nextToken());
+ if (map[i][j] != BLANK && map[i][j] != WALL) {
+ cameras.add(new int[]{i, j});
+ }
+ if (map[i][j] != BLANK) {
+ visited[i][j] = -1;
+ }
+ }
+ }
+
+ dfs(0, visited);
+ System.out.println(answer);
+ }
+
+ public static void dfs(int cameraIdx, int[][] visited) {
+ if (cameraIdx >= cameras.size()) {
+ answer = Math.min(answer, countBlank(visited));
+ return;
+ }
+
+ int[] cameraLocation = cameras.get(cameraIdx);
+ int cameraType = map[cameraLocation[0]][cameraLocation[1]];
+ int[][] todo; // 카메라의 방향의 경우의 수
+
+ if (cameraType == 1) {
+ todo = ONE;
+ } else if (cameraType == 2) {
+ todo = TWO;
+ } else if (cameraType == 3) {
+ todo = THREE;
+ } else if (cameraType == 4) {
+ todo = FOUR;
+ } else {
+ todo = FIVE;
+ }
+
+ for (int i = 0; i < todo.length; i++) {
+ int[][] tmpVisited = new int[visited.length][visited[0].length];
+ for (int k = 0; k < visited.length; k++) {
+ tmpVisited[k] = Arrays.copyOf(visited[k], visited[k].length);
+ }
+
+ for (int j = 0; j < todo[i].length; j++) {
+ int nextI = cameraLocation[0] + move[todo[i][j]][0];
+ int nextJ = cameraLocation[1] + move[todo[i][j]][1];
+
+ while (isInBound(nextI, nextJ) && map[nextI][nextJ] != WALL) {
+ tmpVisited[nextI][nextJ] = -1;
+
+ nextI = nextI + move[todo[i][j]][0];
+ nextJ = nextJ + move[todo[i][j]][1];
+ }
+
+ dfs(cameraIdx + 1, tmpVisited);
+ }
+ }
+
+ }
+
+ public static int countBlank(int[][] visited) {
+ int cnt = 0;
+
+ for (int i = 0; i < visited.length; i++) {
+ for (int j = 0; j < visited[i].length; j++) {
+ if (visited[i][j] == BLANK) {
+ cnt++;
+ }
+ }
+ }
+
+ return cnt;
+ }
+
+ public static boolean isInBound(int i, int j) {
+ return i >= 0 && j >= 0 && i < map.length && j < map[0].length;
+ }
+}
diff --git a/eonju/BOJ/BOJ_16927.java b/eonju/BOJ/BOJ_16927.java
new file mode 100644
index 0000000..0c7e959
--- /dev/null
+++ b/eonju/BOJ/BOJ_16927.java
@@ -0,0 +1,73 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+
+class Main {
+
+ private static int[][] map;
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
+ String[] input = bufferedReader.readLine().split(" ");
+ int height = Integer.parseInt(input[0]);
+ int width = Integer.parseInt(input[1]);
+ int turnCnt = Integer.parseInt(input[2]);
+
+ map = new int[height][width];
+ for (int i = 0; i < height; i++) {
+ map[i] = Arrays.stream(bufferedReader.readLine().split(" "))
+ .mapToInt(Integer::parseInt)
+ .toArray();
+ }
+
+ int startI = 0;
+ int endI = height - 1;
+ int startJ = 0;
+ int endJ = width - 1;
+
+ while (true) {
+ int blockCnt = (endI - startI + 1) * 2 + (endJ - startJ + 1) * 2 - 4;
+ turn(turnCnt % blockCnt, startI, endI, startJ, endJ);
+ startI++;
+ endI--;
+ startJ++;
+ endJ--;
+ if (startI > endI || startJ > endJ) {
+ break;
+ }
+ }
+
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ System.out.print(map[i][j] + " ");
+ }
+ System.out.println();
+ }
+ }
+
+ public static void turn(int turnCnt, int startI, int endI, int startJ, int endJ) {
+ for (int k = 0; k < turnCnt; k++) {
+
+ int temp = map[startI][startJ];
+
+ for (int j = startJ; j < endJ; j++) {
+ map[startI][j] = map[startI][j + 1];
+ }
+
+ for (int i = startI; i < endI; i++) {
+ map[i][endJ] = map[i + 1][endJ];
+ }
+
+ for (int j = endJ; j > startJ; j--) {
+ map[endI][j] = map[endI][j - 1];
+ }
+
+ for (int i = endI; i > startI; i--) {
+ map[i][startJ] = map[i - 1][startJ];
+ }
+
+ map[startI + 1][startJ] = temp;
+ }
+ }
+}
diff --git a/eonju/BOJ/BOJ_17090.java b/eonju/BOJ/BOJ_17090.java
new file mode 100644
index 0000000..72b0788
--- /dev/null
+++ b/eonju/BOJ/BOJ_17090.java
@@ -0,0 +1,124 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Objects;
+
+class Main {
+
+ private static int height;
+ private static int width;
+ private static int answer;
+ private static HashMap> dp;
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
+
+ String[] input = bufferedReader.readLine().split(" ");
+
+ height = Integer.parseInt(input[0]);
+ width = Integer.parseInt(input[1]);
+
+ String[][] map = new String[height][width];
+ dp = new HashMap<>();
+ ArrayList positions = new ArrayList<>();
+
+ for (int i = 0; i < height; i++) {
+ map[i] = bufferedReader.readLine().split("");
+ for (int j = 0; j < map[i].length; j++) {
+ if (map[i][j].equals("U")) {
+ if (isInBound(i - 1, j)) {
+ Position next = new Position(i - 1, j);
+ dp.putIfAbsent(next, new ArrayList<>());
+ dp.get(next).add(new Position(i, j));
+ } else {
+ positions.add(new Position(i, j));
+ }
+ } else if (map[i][j].equals("R")) {
+ if (isInBound(i, j + 1)) {
+ Position next = new Position(i, j + 1);
+ dp.putIfAbsent(next, new ArrayList<>());
+ dp.get(next).add(new Position(i, j));
+ } else {
+ positions.add(new Position(i, j));
+ }
+
+ } else if (map[i][j].equals("L")) {
+ if (isInBound(i, j - 1)) {
+ Position next = new Position(i, j - 1);
+ dp.putIfAbsent(next, new ArrayList<>());
+ dp.get(next).add(new Position(i, j));
+ } else {
+ positions.add(new Position(i, j));
+ }
+
+ } else if (map[i][j].equals("D")) {
+ if (isInBound(i + 1, j)) {
+ Position next = new Position(i + 1, j);
+ dp.putIfAbsent(next, new ArrayList<>());
+ dp.get(next).add(new Position(i, j));
+ } else {
+ positions.add(new Position(i, j));
+ }
+
+ }
+ }
+ }
+
+ answer = 0;
+
+ for (Position position : positions) {
+ answer++;
+ countBlock(position);
+ }
+
+ System.out.println(answer);
+ }
+
+ public static void countBlock(Position position) {
+ if (!dp.containsKey(position)) {
+ return;
+ }
+
+ List positions = dp.get(position);
+ answer += positions.size();
+
+ for (Position next : positions) {
+ countBlock(next);
+ }
+ }
+
+ public static boolean isInBound(int i, int j) {
+ return i >= 0 && j >= 0 && i < height && j < width;
+ }
+
+ static class Position {
+
+ int positionI;
+ int positionJ;
+
+ public Position(int positionI, int positionJ) {
+ this.positionI = positionI;
+ this.positionJ = positionJ;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Position position = (Position) o;
+ return positionI == position.positionI && positionJ == position.positionJ;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(positionI, positionJ);
+ }
+ }
+}
diff --git a/eonju/BOJ/BOJ_1780.java b/eonju/BOJ/BOJ_1780.java
new file mode 100644
index 0000000..caf6429
--- /dev/null
+++ b/eonju/BOJ/BOJ_1780.java
@@ -0,0 +1,67 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+
+class Main {
+
+ private static int MINUS = 0;
+ private static int ZERO = 0;
+ private static int PLUS = 0;
+ private static int[][] map;
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
+
+ int n = Integer.parseInt(bufferedReader.readLine());
+ map = new int[n][n];
+
+ for (int i = 0; i < n; i++) {
+ map[i] = Arrays.stream(bufferedReader.readLine().split(" "))
+ .mapToInt(Integer::parseInt)
+ .toArray();
+ }
+
+ divide(0, 0, n);
+ System.out.println(MINUS);
+ System.out.println(ZERO);
+ System.out.println(PLUS);
+
+ }
+
+ public static void divide(int startI, int startJ, int size) {
+ if (check(startI, startJ, size)) {
+ return;
+ }
+
+ int tmp = size / 3;
+
+ for (int i = startI; i < startI + size; i += tmp) {
+ for (int j = startJ; j < startJ + size; j += tmp) {
+ divide(i, j, tmp);
+ }
+ }
+ }
+
+ public static boolean check(int startI, int startJ, int size) {
+ int number = map[startI][startJ];
+
+ for (int i = startI; i < startI + size; i++) {
+ for (int j = startJ; j < startJ + size; j++) {
+ if (number != map[i][j]) {
+ return false;
+ }
+ }
+ }
+
+ if (number == -1) {
+ MINUS++;
+ } else if (number == 0) {
+ ZERO++;
+ } else {
+ PLUS++;
+ }
+
+ return true;
+ }
+}
diff --git a/eonju/BOJ/BOJ_18808.java b/eonju/BOJ/BOJ_18808.java
new file mode 100644
index 0000000..801a70e
--- /dev/null
+++ b/eonju/BOJ/BOJ_18808.java
@@ -0,0 +1,123 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+
+class Main {
+
+ private static boolean[][] map;
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
+ String[] input = bufferedReader.readLine().split(" ");
+ int mapHeight = Integer.parseInt(input[0]);
+ int mapWidth = Integer.parseInt(input[1]);
+ int stickerQuantity = Integer.parseInt(input[2]);
+
+ map = new boolean[mapHeight][mapWidth];
+
+ Sticker[] stickers = new Sticker[stickerQuantity];
+
+ for (int i = 0; i < stickerQuantity; i++) {
+ input = bufferedReader.readLine().split(" ");
+ int height = Integer.parseInt(input[0]);
+ int width = Integer.parseInt(input[1]);
+ int[][] shape = new int[height][width];
+
+ for (int j = 0; j < height; j++) {
+ shape[j] = Arrays.stream(bufferedReader.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
+ }
+
+ stickers[i] = new Sticker(height, width, shape);
+ }
+
+ for (int i = 0; i < stickers.length; i++) {
+ findLocationAndShape(stickers[i]);
+ }
+
+ int answer = 0;
+ for (int i = 0; i < map.length; i++) {
+ for (int j = 0; j < map[i].length; j++) {
+ if (map[i][j]) {
+ answer++;
+ }
+ }
+ }
+
+ System.out.println(answer);
+ }
+
+ public static void findLocationAndShape(Sticker sticker) {
+ while (sticker.turnCnt <= 3) {
+ for (int i = 0; i < map.length; i++) {
+ for (int j = 0; j < map[i].length; j++) {
+ if (isInBound(sticker.height, sticker.width, i, j) && check(i, j, sticker)) {
+ return;
+ }
+ }
+ }
+ sticker.turn();
+ }
+ }
+
+ public static boolean check(int height, int width, Sticker sticker) {
+ int[][] shape = sticker.shape;
+ boolean[][] tmpMap = copyMap();
+
+ for (int i = height; i < height + sticker.height; i++) {
+ for (int j = width; j < width + sticker.width; j++) {
+ if (map[i][j] && shape[i - height][j - width] == 1) {
+ return false;
+ } else if (!map[i][j] && shape[i - height][j - width] == 1) {
+ tmpMap[i][j] = true;
+ }
+ }
+ }
+
+ map = tmpMap;
+ return true;
+ }
+
+ public static boolean[][] copyMap() {
+ boolean[][] copyMap = new boolean[map.length][map[0].length];
+ for (int i = 0; i < map.length; i++) {
+ copyMap[i] = Arrays.copyOf(map[i], map[i].length);
+ }
+
+ return copyMap;
+ }
+
+ public static boolean isInBound(int stickerHeight, int stickerWidth, int height, int width) {
+ return height + stickerHeight <= map.length && width + stickerWidth <= map[0].length;
+ }
+
+ static class Sticker {
+
+ int height;
+ int width;
+ int[][] shape;
+ int turnCnt;
+
+ public Sticker(int height, int width, int[][] shape) {
+ this.height = height;
+ this.width = width;
+ this.shape = shape;
+ this.turnCnt = 0;
+ }
+
+ public void turn() {
+ turnCnt++;
+ int[][] newShape = new int[width][height];
+
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ newShape[j][height - i - 1] = shape[i][j];
+ }
+ }
+
+ this.height = newShape.length;
+ this.width = newShape[0].length;
+ this.shape = newShape;
+ }
+ }
+}
diff --git a/eonju/BOJ/BOJ_1922.java b/eonju/BOJ/BOJ_1922.java
new file mode 100644
index 0000000..c527e87
--- /dev/null
+++ b/eonju/BOJ/BOJ_1922.java
@@ -0,0 +1,92 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Comparator;
+import java.util.PriorityQueue;
+
+class Main {
+
+ private static int[] parent;
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
+ int computerQuantity = Integer.parseInt(bufferedReader.readLine());
+ int lineQuantity = Integer.parseInt(bufferedReader.readLine());
+
+ parent = new int[computerQuantity + 1];
+ for (int i = 1; i <= computerQuantity; i++) {
+ parent[i] = i;
+ }
+
+ PriorityQueue queue = new PriorityQueue<>(Comparator.comparingInt(Edge::getWeight));
+ for (int i = 0; i < lineQuantity; i++) {
+ String[] input = bufferedReader.readLine().split(" ");
+ int targetA = Integer.parseInt(input[0]);
+ int targetB = Integer.parseInt(input[1]);
+ int weight = Integer.parseInt(input[2]);
+
+ queue.add(new Edge(Math.min(targetA, targetB), Math.max(targetA, targetB), weight));
+ }
+
+ int answer = 0;
+
+ while (!queue.isEmpty()) {
+ Edge poll = queue.poll();
+ int a = poll.getStart();
+ int b = poll.getEnd();
+ int weight = poll.getWeight();
+
+ int parentA = find(a);
+ int parentB = find(b);
+
+ if (parentA != parentB) {
+ union(a, b);
+ answer += weight;
+ }
+ }
+
+ System.out.println(answer);
+ }
+
+ public static void union(int a, int b) {
+ int rootA = find(a);
+ int rootB = find(b);
+
+ if (rootA != rootB) {
+ parent[rootB] = a;
+ }
+ }
+
+ public static int find(int a) {
+ if (parent[a] == a) {
+ return a;
+ }
+
+ return parent[a] = find(parent[a]);
+ }
+
+ static class Edge {
+
+ private int start;
+ private int end;
+ private int weight;
+
+ public Edge(int start, int end, int weight) {
+ this.start = start;
+ this.end = end;
+ this.weight = weight;
+ }
+
+ public int getStart() {
+ return start;
+ }
+
+ public int getEnd() {
+ return end;
+ }
+
+ public int getWeight() {
+ return weight;
+ }
+ }
+}
diff --git a/eonju/BOJ/BOJ_1963.java b/eonju/BOJ/BOJ_1963.java
new file mode 100644
index 0000000..b2d4ddd
--- /dev/null
+++ b/eonju/BOJ/BOJ_1963.java
@@ -0,0 +1,110 @@
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.Scanner;
+
+
+class Main {
+
+ static int testCase;
+ static boolean[] primeNumber = new boolean[10000];
+ static int answer;
+
+ public static void main(String[] args) {
+ Scanner sc = new Scanner(System.in);
+ testCase = sc.nextInt();
+ makePrimeNumber();
+ int a, b;
+
+ while (testCase-- > 0) {
+ answer = Integer.MAX_VALUE;
+ a = sc.nextInt();
+ b = sc.nextInt();
+ System.out.println(solve(a, b) == Integer.MAX_VALUE ? "Impossible" : answer);
+ }
+ }
+
+ public static void makePrimeNumber() {
+ for (int i = 2; i <= 9999; i++) {
+ if (primeNumber[i] == false) {
+ for (int j = 2 * i; j <= 9999; j += i) {
+ primeNumber[j] = true;
+ }
+ }
+ }
+ }
+
+ public static int solve(int a, int b) {
+ boolean[] visited = new boolean[10000];
+ visited[a] = true;
+ Queue q = new LinkedList<>();
+ q.add(new Prime(a, 0));
+ while (!q.isEmpty()) {
+ Prime p = q.poll();
+
+ if (p.number == b) {
+ answer = Math.min(answer, p.cnt);
+ }
+
+ for (int i = 0; i <= 9; i++) {
+ if (i != p.get4()) {
+ int next = i * 1000 + p.get3() * 100 + p.get2() * 10 + p.get1();
+ if (1000 <= next && !primeNumber[next] && !visited[next]) {
+ visited[next] = true;
+ q.add(new Prime(next, p.cnt + 1));
+ }
+ }
+ if (i != p.get3()) {
+ int next = p.get4() * 1000 + i * 100 + p.get2() * 10 + p.get1();
+ if (1000 <= next && !primeNumber[next] && !visited[next]) {
+ visited[next] = true;
+ q.add(new Prime(next, p.cnt + 1));
+ }
+ }
+ if (i != p.get2()) {
+ int next = p.get4() * 1000 + p.get3() * 100 + i * 10 + p.get1();
+ if (1000 <= next && !primeNumber[next] && !visited[next]) {
+ visited[next] = true;
+ q.add(new Prime(next, p.cnt + 1));
+ }
+ }
+ if (i != p.get1()) {
+ int next = p.get4() * 1000 + p.get3() * 100 + p.get2() * 10 + i;
+ if (1000 <= next && !primeNumber[next] && !visited[next]) {
+ visited[next] = true;
+ q.add(new Prime(next, p.cnt + 1));
+ }
+ }
+ }
+ }
+
+ return answer;
+ }
+
+
+ static class Prime {
+
+ int number;
+ int cnt;
+
+ public Prime(int number, int cnt) {
+ this.number = number;
+ this.cnt = cnt;
+ }
+
+ public int get1() {
+ return number % 10;
+ }
+
+ public int get2() {
+ return (number % 100) / 10;
+ }
+
+ public int get3() {
+ return (number % 1000) / 100;
+ }
+
+ public int get4() {
+ return (number) / 1000;
+ }
+ }
+}
diff --git a/eonju/BOJ/BOJ_20055.java b/eonju/BOJ/BOJ_20055.java
new file mode 100644
index 0000000..0a0af27
--- /dev/null
+++ b/eonju/BOJ/BOJ_20055.java
@@ -0,0 +1,85 @@
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.StringTokenizer;
+
+public class Main {
+
+ static int n, k, map[], left, right;
+ static boolean robot[];
+
+ public static void main(String[] args) throws Exception {
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+
+ n = Integer.parseInt(stz.nextToken());
+ k = Integer.parseInt(stz.nextToken());
+ map = new int[2 * n];
+ robot = new boolean[n];
+ stz = new StringTokenizer(br.readLine());
+ for (int i = 0; i < 2 * n; i++) {
+ map[i] = Integer.parseInt(stz.nextToken());
+ }
+ left = 0;
+ right = n;
+
+ int count = 0;
+ while (k > 0) {
+ count++;
+ moveBelt();
+ moveRobot();
+ newRobot();
+ }
+
+ System.out.println(count);
+ }
+
+ public static void moveBelt() {
+ left--;
+ right--;
+ if (left == -1) {
+ left = 2 * n - 1;
+ }
+ if (right == -1) {
+ right = 2 * n - 1;
+ }
+
+ for (int i = n - 2; i >= 0; i--) {
+ if (robot[i]) {
+ robot[i] = false;
+ if (i + 1 < n - 1) {
+ robot[i + 1] = true;
+ }
+ }
+ }
+ }
+
+ public static void moveRobot() {
+ for (int i = n - 2; i >= 0; i--) {
+ if (robot[i]) {
+ int next = left + i + 1;
+ if (next >= 2 * n) {
+ next -= 2 * n;
+ }
+ if (!robot[i + 1] && map[next] >= 1) {
+ robot[i] = false;
+ if (i + 1 < n - 1) {
+ robot[i + 1] = true;
+ }
+ map[next]--;
+ if (map[next] == 0) {
+ k--;
+ }
+ }
+ }
+ }
+ }
+
+ public static void newRobot() {
+ if (!robot[0] && map[left] > 0) {
+ robot[0] = true;
+ map[left]--;
+ if (map[left] == 0) {
+ k--;
+ }
+ }
+ }
+}
diff --git a/eonju/BOJ/BOJ_20056.java b/eonju/BOJ/BOJ_20056.java
new file mode 100644
index 0000000..d300e95
--- /dev/null
+++ b/eonju/BOJ/BOJ_20056.java
@@ -0,0 +1,131 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+class Main {
+
+ private static final int[][] moveDirection = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
+ private static final int[] sameDirection = {0, 2, 4, 6};
+ private static final int[] diffDirection = {1, 3, 5, 7};
+ private static Fireball[][] map;
+ private static int mapSize;
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
+ String[] input = bufferedReader.readLine().split(" ");
+ mapSize = Integer.parseInt(input[0]);
+ int fireballCnt = Integer.parseInt(input[1]);
+ int moveCnt = Integer.parseInt(input[2]);
+
+ map = new Fireball[mapSize][mapSize];
+
+ for (int i = 0; i < fireballCnt; i++) {
+ input = bufferedReader.readLine().split(" ");
+ int height = Integer.parseInt(input[0]);
+ int width = Integer.parseInt(input[1]);
+ int weight = Integer.parseInt(input[2]);
+ int speed = Integer.parseInt(input[3]);
+ int direction = Integer.parseInt(input[4]);
+
+ map[height][width] = new Fireball(weight, direction, speed);
+ }
+
+ for (int i = 0; i < moveCnt; i++) {
+ int[][] fireballCntMap = move();
+ arrangeMap(fireballCntMap);
+ }
+
+ }
+
+ public static void arrangeMap(int[][] fireballCntMap) {
+ for (int i = 0; i < fireballCntMap.length; i++) {
+ for (int j = 0; j < fireballCntMap[i].length; j++) {
+ if (fireballCntMap[i][j] >= 2) {
+ Fireball fireball = map[i][j];
+ int nextWeight = fireball.weight / 5;
+ int nextSpeed = fireball.speed / fireballCntMap[i][j];
+ if (fireball.direction == -1) {
+ for (int direction = 0; direction < diffDirection.length; direction++) {
+
+ }
+ } else {
+ for (int direction = 0; direction < sameDirection.length; direction++) {
+
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public static int[][] move() {
+ int[][] fireballCntMap = new int[map.length][map[0].length];
+ for (int i = 0; i < map.length; i++) {
+ for (int j = 0; j < map[i].length; j++) {
+ if (map[i][j] != null) {
+ Fireball fireball = map[i][j];
+ int[] direction = moveDirection[fireball.direction];
+ int nextHeight;
+ int nextWidth;
+ for (int k = 0; k < fireball.speed; k++) {
+ nextHeight = i + direction[0];
+ nextWidth = j + direction[1];
+
+ if (nextHeight == -1) {
+ nextHeight = mapSize - 1;
+ } else if (nextHeight >= mapSize) {
+ nextHeight = 0;
+ }
+
+ if (nextWidth == -1) {
+ nextWidth = mapSize - 1;
+ } else if (nextWidth >= mapSize) {
+ nextWidth = 0;
+ }
+
+ if (map[nextHeight][nextWidth] != null) {
+ merge(nextHeight, nextWidth, fireball.weight, fireball.direction, fireball.speed);
+ } else {
+ map[nextHeight][nextWidth] = new Fireball(fireball.weight, fireball.direction,
+ fireball.speed);
+ }
+ fireballCntMap[nextHeight][nextWidth] = fireballCntMap[nextHeight][nextWidth] + 1;
+ }
+ }
+ }
+ }
+
+ return fireballCntMap;
+ }
+
+
+ public static void merge(int height, int width, int weight, int direction, int speed) {
+ Fireball fireball = map[height][width];
+ if (isSameKindOfDirection(fireball.direction, direction)) {
+ map[height][width] = new Fireball(fireball.weight + weight, fireball.direction, fireball.speed + speed);
+ } else {
+ map[height][width] = new Fireball(fireball.weight + weight, -1, fireball.speed + speed);
+ }
+ }
+
+ public static boolean isSameKindOfDirection(int directionA, int directionB) {
+ if (directionA == -1 || directionB == -1) {
+ return false;
+ }
+
+ return directionA % 2 == 0 && directionB % 2 == 0;
+ }
+
+ static class Fireball {
+
+ int weight;
+ int direction;
+ int speed;
+
+ public Fireball(int weight, int direction, int speed) {
+ this.weight = weight;
+ this.direction = direction;
+ this.speed = speed;
+ }
+ }
+}
diff --git a/eonju/BOJ/BOJ_22352.java b/eonju/BOJ/BOJ_22352.java
new file mode 100644
index 0000000..611bedd
--- /dev/null
+++ b/eonju/BOJ/BOJ_22352.java
@@ -0,0 +1,110 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.StringTokenizer;
+
+public class Main {
+
+ static int N, M;
+ static int[][] beforeMap;
+ static int[][] afterMap;
+
+ static int[] moveX = {1, -1, 0, 0};
+ static int[] moveY = {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());
+
+ N = Integer.parseInt(st.nextToken());
+ M = Integer.parseInt(st.nextToken());
+
+ beforeMap = new int[N][M];
+ afterMap = new int[N][M];
+
+ for (int i = 0; i < N; i++) {
+ st = new StringTokenizer(br.readLine());
+ for (int j = 0; j < M; j++) {
+ beforeMap[i][j] = Integer.parseInt(st.nextToken());
+ }
+ }
+ for (int i = 0; i < N; i++) {
+ st = new StringTokenizer(br.readLine());
+ for (int j = 0; j < M; j++) {
+ afterMap[i][j] = Integer.parseInt(st.nextToken());
+ }
+ }
+ start();
+ if (check()) {
+ System.out.println("YES");
+ } else {
+ System.out.println("NO");
+ }
+
+ }
+
+ public static void start() {
+ for (int y = 0; y < N; y++) {
+ for (int x = 0; x < M; x++) {
+ if (beforeMap[y][x] != afterMap[y][x]) {
+ BFS(x, y, afterMap[y][x]);
+ return;
+ }
+ }
+ }
+ }
+
+ public static boolean check() {
+ for (int y = 0; y < N; y++) {
+ for (int x = 0; x < M; x++) {
+ if (beforeMap[y][x] != afterMap[y][x]) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public static void BFS(int x, int y, int val) {
+ Queue q = new LinkedList<>();
+ q.add(new Point(x, y));
+
+ boolean[][] visited = new boolean[N][M];
+ visited[y][x] = true;
+
+ int lastVal = beforeMap[y][x];
+ beforeMap[y][x] = val;
+
+ while (!q.isEmpty()) {
+ Point cur = q.poll();
+
+ for (int i = 0; i < 4; i++) {
+ int nextX = cur.x + moveX[i];
+ int nextY = cur.y + moveY[i];
+
+ if (nextX < 0 || nextX >= M || nextY < 0 || nextY >= N) {
+ continue;
+ }
+ if (!visited[nextY][nextX] && beforeMap[nextY][nextX] == lastVal) {
+ q.add(new Point(nextX, nextY));
+ visited[nextY][nextX] = true;
+ beforeMap[nextY][nextX] = val;
+ }
+ }
+ }
+ }
+}
+
+class Point {
+
+ int x;
+ int y;
+
+ public Point(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+}
diff --git a/eonju/BOJ/BOJ_2573.java b/eonju/BOJ/BOJ_2573.java
new file mode 100644
index 0000000..258d6dc
--- /dev/null
+++ b/eonju/BOJ/BOJ_2573.java
@@ -0,0 +1,127 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.LinkedList;
+import java.util.Queue;
+
+class Main {
+
+ private static int time = 0;
+ private static int[][] map;
+ private static final int[][] move = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
+ String[] input = bufferedReader.readLine().split(" ");
+ int height = Integer.parseInt(input[0]);
+ int width = Integer.parseInt(input[1]);
+
+ map = new int[height][width];
+ for (int i = 0; i < height; i++) {
+ input = bufferedReader.readLine().split(" ");
+ for (int j = 0; j < width; j++) {
+ map[i][j] = Integer.parseInt(input[j]);
+ }
+ }
+
+ int cnt = check();
+ while (cnt == 1) {
+ time++;
+ int[][] minusMap = new int[height][width];
+ makeMinusMap(minusMap);
+ melt(minusMap);
+
+ cnt = check();
+ }
+
+ if (cnt == -1) {
+ System.out.println(0);
+ } else {
+ System.out.println(time);
+ }
+ }
+
+ public static void makeMinusMap(int[][] minusMap) {
+ for (int i = 0; i < map.length; i++) {
+ for (int j = 0; j < map[i].length; j++) {
+ if (map[i][j] != 0) {
+ int cnt = 0;
+ for (int location = 0; location < move.length; location++) {
+ int nextI = i + move[location][0];
+ int nextJ = j + move[location][1];
+
+ if (nextI < 0 || nextJ < 0 || nextI >= minusMap.length || nextJ >= minusMap[0].length) {
+ continue;
+ }
+
+ if (map[nextI][nextJ] == 0) {
+ cnt++;
+ }
+ }
+ minusMap[i][j] = cnt;
+ }
+ }
+ }
+ }
+
+ public static void melt(int[][] minusMap) {
+ for (int i = 0; i < minusMap.length; i++) {
+ for (int j = 0; j < minusMap[i].length; j++) {
+ if (minusMap[i][j] != 0) {
+ if (map[i][j] - minusMap[i][j] > 0) {
+ map[i][j] = map[i][j] - minusMap[i][j];
+ } else {
+ map[i][j] = 0;
+ }
+ }
+ }
+ }
+ }
+
+ public static int check() {
+ int cnt = 0;
+
+ boolean[][] visited = new boolean[map.length][map[0].length];
+ for (int i = 0; i < map.length; i++) {
+ for (int j = 0; j < map[i].length; j++) {
+ if (map[i][j] != 0 && !visited[i][j]) {
+ bfs(visited, i, j);
+ cnt++;
+ }
+ }
+ }
+
+ if (cnt == 0) {
+ return -1;
+ } else {
+ return cnt;
+ }
+ }
+
+ public static void bfs(boolean[][] visited, int startI, int startJ) {
+ Queue queue = new LinkedList<>();
+
+ queue.add(new int[]{startI, startJ});
+ visited[startI][startJ] = true;
+ while (!queue.isEmpty()) {
+ int[] now = queue.poll();
+ for (int i = 0; i < move.length; i++) {
+ int nextI = now[0] + move[i][0];
+ int nextJ = now[1] + move[i][1];
+
+ if (nextI < 0 || nextJ < 0 || nextI >= map.length || nextJ >= map[0].length) {
+ continue;
+ }
+
+ if (visited[nextI][nextJ]) {
+ continue;
+ }
+
+ if (map[nextI][nextJ] != 0) {
+ visited[nextI][nextJ] = true;
+ queue.add(new int[]{nextI, nextJ});
+ }
+ }
+ }
+ }
+}
diff --git a/eonju/BOJ/BOJ_2580.java b/eonju/BOJ/BOJ_2580.java
new file mode 100644
index 0000000..1396c83
--- /dev/null
+++ b/eonju/BOJ/BOJ_2580.java
@@ -0,0 +1,105 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+
+class Main {
+
+ private static int[][] map;
+ private static int[][] answer;
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
+
+ map = new int[9][9];
+ answer = new int[9][9];
+
+ for (int i = 0; i < 9; i++) {
+ map[i] = Arrays.stream(bufferedReader.readLine().split(" "))
+ .mapToInt(Integer::parseInt)
+ .toArray();
+ }
+
+ fillNumber(0, 0);
+
+ for (int i = 0; i < 9; i++) {
+ for (int j = 0; j < 9; j++) {
+ System.out.print(answer[i][j] + " ");
+ }
+ System.out.println();
+ }
+ }
+
+ public static void fillNumber(int startI, int startJ) {
+ if (startI == 8 && startJ == 8 && map[startI][startJ] != 0) {
+ for (int i = 0; i < map.length; i++) {
+ answer[i] = Arrays.copyOf(map[i], map[i].length);
+ }
+ return;
+ }
+
+ for (int i = 0; i < 9; i++) {
+ for (int j = 0; j < 9; j++) {
+ if (map[i][j] == 0) {
+ for (int num = 1; num <= 9; num++) {
+ map[i][j] = num;
+ if (checkMiniMap(i, j) && checkHorizontal(i) && checkVertical(j)) {
+ fillNumber(i, j);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public static boolean checkMiniMap(int i, int j) {
+ int startI = (i / 3) * 3;
+ int startJ = (j / 3) * 3;
+
+ boolean[] visited = new boolean[10];
+ for (int height = startI; height < startI + 3; height++) {
+ for (int width = startJ; width < startJ + 3; width++) {
+ int number = map[height][width];
+ if (number == 0) {
+ continue;
+ }
+ if (visited[number]) {
+ return false;
+ } else {
+ visited[number] = true;
+ }
+ }
+ }
+ return true;
+ }
+
+ public static boolean checkHorizontal(int i) {
+ boolean[] visited = new boolean[10];
+
+ for (int width = 0; width < 9; width++) {
+ int number = map[i][width];
+ if (visited[number]) {
+ return false;
+ } else {
+ visited[number] = true;
+ }
+ }
+
+ return true;
+ }
+
+ public static boolean checkVertical(int j) {
+ boolean[] visited = new boolean[10];
+
+ for (int height = 0; height < 9; height++) {
+ int number = map[height][j];
+ if (visited[number]) {
+ return false;
+ } else {
+ visited[number] = true;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/eonju/BOJ/BOJ_3151.java b/eonju/BOJ/BOJ_3151.java
new file mode 100644
index 0000000..28690f6
--- /dev/null
+++ b/eonju/BOJ/BOJ_3151.java
@@ -0,0 +1,68 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+
+class Main {
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
+ int n = Integer.parseInt(bufferedReader.readLine());
+ int[] numbers = new int[n];
+
+ String[] input = bufferedReader.readLine().split(" ");
+ for (int i = 0; i < numbers.length; i++) {
+ numbers[i] = Integer.parseInt(input[i]);
+ }
+
+ Arrays.sort(numbers);
+
+ long answer = 0L;
+
+ for (int i = 0; i < numbers.length; i++) {
+ if (numbers[i] > 0) {
+ break;
+ }
+
+ int leftIdx = i + 1;
+ int rightIdx = n - 1;
+ while (leftIdx < rightIdx) {
+ int leftCnt = 1;
+ int rightCnt = 1;
+
+ int current = numbers[i] + numbers[leftIdx] + numbers[rightIdx];
+
+ if (current == 0) {
+ if (numbers[leftIdx] == numbers[rightIdx]) {
+ answer += comb(rightIdx - leftIdx + 1);
+ break;
+ }
+
+ while (leftIdx + 1 < rightIdx && numbers[leftIdx] == numbers[leftIdx + 1]) {
+ leftCnt++;
+ leftIdx++;
+ }
+
+ while (leftIdx < rightIdx - 1 && numbers[rightIdx] == numbers[rightIdx - 1]) {
+ rightCnt++;
+ rightIdx--;
+ }
+
+ answer += leftCnt * rightCnt;
+ }
+
+ if (current > 0) {
+ rightIdx--;
+ } else {
+ leftIdx++;
+ }
+ }
+ }
+
+ System.out.println(answer);
+ }
+
+ public static int comb(int x) {
+ return x * (x - 1) / 2;
+ }
+}
diff --git a/eonju/BOJ/BOJ_5557.java b/eonju/BOJ/BOJ_5557.java
new file mode 100644
index 0000000..669b350
--- /dev/null
+++ b/eonju/BOJ/BOJ_5557.java
@@ -0,0 +1,48 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+class Main {
+
+ private static int[] numbers;
+ private static long[] dp;
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
+ int numberCnt = Integer.parseInt(bufferedReader.readLine());
+
+ numbers = new int[numberCnt];
+
+ String[] input = bufferedReader.readLine().split(" ");
+ for (int i = 0; i < input.length; i++) {
+ numbers[i] = Integer.parseInt(input[i]);
+ }
+
+ dp = new long[21];
+ dp[numbers[0]] = 1;
+ solve(1);
+ System.out.println(dp[numbers[numbers.length - 1]]);
+ }
+
+ public static void solve(int idx) {
+ if (idx == numbers.length - 1) {
+ return;
+ }
+
+ long temp[] = new long[21];
+ for (int i = 0; i < dp.length; i++) {
+ if (dp[i] != 0) {
+ if (i + numbers[idx] <= 20) {
+ temp[i + numbers[idx]] += dp[i];
+ }
+ if (i - numbers[idx] >= 0) {
+ temp[i - numbers[idx]] += dp[i];
+ }
+ }
+ }
+
+ dp = temp.clone();
+ solve(idx + 1);
+ }
+
+}
diff --git a/eonju/BOJ/BOJ_5569.java b/eonju/BOJ/BOJ_5569.java
new file mode 100644
index 0000000..6b7db68
--- /dev/null
+++ b/eonju/BOJ/BOJ_5569.java
@@ -0,0 +1,35 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+class Main {
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
+ String[] input = bufferedReader.readLine().split(" ");
+
+ int w = Integer.parseInt(input[0]);
+ int h = Integer.parseInt(input[1]);
+
+ int[][][][] dp = new int[w + 1][h + 1][2][2]; // 3IDX : 방향(0: 오른쪽, 1: 아래) // 4IDX : 꺾었는지 (0: 꺾지않음, 1: 꺾음)
+ for (int i = 1; i <= w; i++) {
+ dp[i][1][0][0] = 1;
+ }
+
+ for (int i = 1; i <= h; i++) {
+ dp[1][i][1][0] = 1;
+ }
+
+ for (int i = 2; i <= w; i++) {
+ for (int j = 2; j <= h; j++) {
+ dp[i][j][1][0] = (dp[i][j - 1][1][1] + dp[i][j - 1][1][0]) % 100000;
+ dp[i][j][1][1] = dp[i][j - 1][0][0] % 100000;
+ dp[i][j][0][0] = (dp[i - 1][j][0][0] + dp[i - 1][j][0][1]) % 100000;
+ dp[i][j][0][1] = dp[i - 1][j][1][0];
+ }
+ }
+
+ int result = (dp[w][h][0][0] + dp[w][h][0][1] + dp[w][h][1][0] + dp[w][h][1][1]) % 100000;
+ System.out.println(result);
+ }
+}
diff --git a/eonju/PMS/PMS_42888.java b/eonju/PMS/PMS_42888.java
new file mode 100644
index 0000000..6f089b9
--- /dev/null
+++ b/eonju/PMS/PMS_42888.java
@@ -0,0 +1,46 @@
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+
+class Solution {
+
+ public static void main(String[] args) {
+ String[] answer = solution(
+ new String[]{"Enter uid1234 Muzi", "Enter uid4567 Prodo", "Leave uid1234", "Enter uid1234 Prodo",
+ "Change uid4567 Ryan"});
+
+ System.out.println(Arrays.toString(answer));
+ }
+
+ public static String[] solution(String[] record) {
+ HashMap names = new HashMap<>();
+
+ for (int i = 0; i < record.length; i++) {
+ String[] input = record[i].split(" ");
+ String command = input[0];
+ String uid = input[1];
+
+ if (command.equals("Enter") || command.equals("Change")) {
+ names.put(uid, input[2]);
+ }
+ }
+
+ ArrayList answer = new ArrayList<>();
+
+ for (int i = 0; i < record.length; i++) {
+ String[] input = record[i].split(" ");
+ String command = input[0];
+ String uid = input[1];
+
+ String name = names.get(uid);
+
+ if (command.equals("Enter")) {
+ answer.add(name + "님이 들어왔습니다.");
+ } else if (command.equals("Leave")) {
+ answer.add(name + "님이 나갔습니다.");
+ }
+ }
+
+ return answer.toArray(new String[0]);
+ }
+}
diff --git a/eonju/PMS/PMS_60061.java b/eonju/PMS/PMS_60061.java
new file mode 100644
index 0000000..04ccecc
--- /dev/null
+++ b/eonju/PMS/PMS_60061.java
@@ -0,0 +1,136 @@
+import java.util.ArrayDeque;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.Iterator;
+
+class Solution {
+
+ static boolean[][] gidung;
+ static boolean[][] boo;
+ static int N;
+ static Deque ansList = new ArrayDeque<>();
+
+ public int[][] solution(int n, int[][] build_frame) {
+ N = n + 1;
+ gidung = new boolean[N][N];
+ for (int i = 0; i < N; i++) {
+ gidung[i] = new boolean[N];
+ }
+ boo = new boolean[N][N];
+ for (int i = 0; i < N; i++) {
+ boo[i] = new boolean[N];
+ }
+
+ for (int[] bf : build_frame) {
+
+ if (bf[2] == 1 && bf[3] == 1) { // 보 설치
+ if (booCheck(bf[0], bf[1])) {
+ boo[bf[0]][bf[1]] = true;
+ ansList.add(new int[]{bf[0], bf[1], 1});
+ }
+ }
+
+ if (bf[2] == 0 && bf[3] == 1) { // 기둥 설치
+ if (gidungCheck(bf[0], bf[1])) {
+ gidung[bf[0]][bf[1]] = true;
+ ansList.add(new int[]{bf[0], bf[1], 0});
+ }
+ }
+
+ if (bf[2] == 0 && bf[3] == 0) { // 기둥 삭제
+ gidung[bf[0]][bf[1]] = false;
+ remove(bf[0], bf[1], bf[2]);
+ if (!allCheck()) {
+ gidung[bf[0]][bf[1]] = true;
+ ansList.add(new int[]{bf[0], bf[1], bf[2]});
+ }
+
+
+ }
+ if (bf[2] == 1 && bf[3] == 0) { // 보 삭제
+ boo[bf[0]][bf[1]] = false;
+ remove(bf[0], bf[1], bf[2]);
+ if (!allCheck()) {
+ boo[bf[0]][bf[1]] = true;
+ ansList.add(new int[]{bf[0], bf[1], bf[2]});
+ }
+
+ }
+
+ }
+
+ return ansListToAnswer();
+ }
+
+ static int[][] ansListToAnswer() {
+
+ Iterator iterator = ansList.iterator();
+ int[][] ans = new int[ansList.size()][3];
+ int i = 0;
+ while (iterator.hasNext()) {
+ ans[i++] = iterator.next();
+ }
+ Arrays.sort(ans, (a, b) -> {
+ if (a[0] != b[0]) {
+ return a[0] - b[0];
+ } else if (a[1] != b[1]) {
+ return a[1] - b[1];
+ } else {
+ return a[2] - b[2];
+ }
+ });
+ return ans;
+ }
+
+ static boolean booCheck(int x, int y) {
+ if (y == 0) {
+ return false; //바닥
+ } else if (gidung[x][y - 1] || gidung[x + 1][y - 1]) { // 양쪽 기둥
+ return true;
+ } else if (x - 1 >= 0 && x + 1 < N && boo[x - 1][y] && boo[x + 1][y]) { // 양쪽 보
+ return true;
+ }
+ return false;
+ }
+
+ static boolean gidungCheck(int x, int y) {
+ if (y == 0) {
+ return true; // 바닥
+ } else if ((x - 1 >= 0 && boo[x - 1][y]) || boo[x][y]) {
+ return true; // 한쪽 끝에 보
+ } else if (y - 1 >= 0 && gidung[x][y - 1]) {
+ return true; //다른 기둥 위에
+ }
+
+ return false;
+ }
+
+ static void remove(int x, int y, int w) {
+ int ansListSize = ansList.size();
+ for (int i = 0; i < ansListSize; i++) {
+ int[] tmp = ansList.pollFirst();
+ if (!(tmp[0] == x && tmp[1] == y && tmp[2] == w)) {
+ ansList.addLast(tmp);
+ }
+ }
+ }
+
+ static boolean allCheck() {
+ Iterator iterator = ansList.iterator();
+ while (iterator.hasNext()) {
+ int[] tmp = iterator.next();
+ if (tmp[2] == 1) {
+ if (!booCheck(tmp[0], tmp[1])) {
+ return false;
+ }
+
+ } else {
+ if (!gidungCheck(tmp[0], tmp[1])) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/eonju/PMS/PMS_60062.java b/eonju/PMS/PMS_60062.java
new file mode 100644
index 0000000..74037a2
--- /dev/null
+++ b/eonju/PMS/PMS_60062.java
@@ -0,0 +1,97 @@
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+class Solution {
+
+ private static List weakCases;
+ private static List distCases;
+ private static int answer;
+
+ public static void main(String[] args) {
+// System.out.println(solution(12, new int[]{1, 5, 6, 10}, new int[]{1, 2, 3, 4}));
+ System.out.println(solution(12, new int[]{1, 3, 4, 9, 10}, new int[]{3, 5, 7}));
+
+ }
+
+ public static int solution(int n, int[] weak, int[] dist) {
+ weakCases = new ArrayList<>();
+ distCases = new ArrayList<>();
+ answer = Integer.MAX_VALUE;
+
+ makeDistCases(0, Arrays.copyOf(dist, dist.length), dist);
+ makeWeakCases(0, Arrays.copyOf(weak, weak.length), weak);
+
+ for (int[] weakCase : weakCases) {
+ for (int[] distCase : distCases) {
+ checkWall(n, weakCase, distCase);
+ }
+ }
+
+ if (answer == Integer.MAX_VALUE) {
+ answer = -1;
+ }
+
+ return answer;
+ }
+
+ public static void checkWall(int n, int[] weakCase, int[] distCase) {
+ boolean[] isFixed = new boolean[n];
+ int distIdx = 0;
+
+ for (int weakArea : weakCase) {
+ if (isFixed[weakArea]) {
+ continue;
+ }
+
+ if (distIdx >= distCase.length) {
+ return;
+ }
+
+ int dist = distCase[distIdx];
+
+ if (weakArea + dist > n) {
+ Arrays.fill(isFixed, weakArea, n, true);
+ Arrays.fill(isFixed, 0, weakArea + dist - n, true);
+ } else {
+ Arrays.fill(isFixed, weakArea, weakArea + dist, true);
+ }
+
+ distIdx++;
+ }
+
+ answer = Math.min(answer, distIdx);
+ }
+
+ public static void makeWeakCases(int depth, int[] tmp, int[] weak) {
+ if (depth == weak.length) {
+ weakCases.add(Arrays.copyOf(tmp, tmp.length));
+ return;
+ }
+
+ for (int i = depth; i < weak.length; i++) {
+ swap(tmp, depth, i);
+ makeWeakCases(depth + 1, tmp, weak);
+ swap(tmp, depth, i);
+ }
+ }
+
+ public static void makeDistCases(int depth, int[] tmp, int[] dist) {
+ if (depth == dist.length) {
+ distCases.add(Arrays.copyOf(tmp, tmp.length));
+ return;
+ }
+
+ for (int i = depth; i < dist.length; i++) {
+ swap(tmp, depth, i);
+ makeDistCases(depth + 1, tmp, dist);
+ swap(tmp, depth, i);
+ }
+ }
+
+ public static void swap(int[] arr, int depth, int i) {
+ int tmp = arr[depth];
+ arr[depth] = arr[i];
+ arr[i] = tmp;
+ }
+}
diff --git a/eonju/PMS/PMS_60063.java b/eonju/PMS/PMS_60063.java
new file mode 100644
index 0000000..97af9d3
--- /dev/null
+++ b/eonju/PMS/PMS_60063.java
@@ -0,0 +1,162 @@
+import java.util.*;
+
+public class Solution {
+
+ public int map[][];
+ public int n;
+ public int dx[] = {-1, 1, 0, 0};
+ public int dy[] = {0, 0, -1, 1};
+ public boolean row[][];
+ public boolean col[][];
+ public int answer;
+
+ public int solution(int[][] board) {
+ n = board.length;
+ answer = 0;
+ row = new boolean[n][n];
+ col = new boolean[n][n];
+ map = new int[n][n];
+ for (int i = 0; i < n; i++) {
+ map[i] = board[i].clone();
+ }
+
+ row[0][0] = true;
+ row[0][1] = true;
+
+ start();
+
+ return answer;
+ }
+
+ public void start() {
+ Queue q = new LinkedList();
+ q.add(new Robot(new Point(0, 0), new Point(0, 1), 0));
+ q.add(new Robot(null, null, -1));
+ int count = 0;
+
+ while (!q.isEmpty()) {
+ Robot now = q.poll();
+
+ if (now.dir == -1) {
+ count++;
+ if (!q.isEmpty()) {
+ q.add(new Robot(null, null, -1));
+ }
+ continue;
+ }
+
+ if ((now.p1.x == n - 1 && now.p1.y == n - 1) || (now.p2.x == n - 1 && now.p2.y == n - 1)) {
+ answer = count;
+ break;
+ }
+
+ if (now.dir == 0) {
+ for (int i = 0; i < 4; i++) {
+ int np1X = now.p1.x + dx[i];
+ int np1Y = now.p1.y + dy[i];
+ int np2X = now.p2.x + dx[i];
+ int np2Y = now.p2.y + dy[i];
+
+ if (check(np1X, np1Y) && check(np2X, np2Y)) {
+ if (!row[np1X][np1Y] || !row[np2X][np2Y]) {
+ Robot next = new Robot(new Point(np1X, np1Y), new Point(np2X, np2Y), 0);
+ row[np1X][np1Y] = true;
+ row[np2X][np2Y] = true;
+ q.add(next);
+ }
+ }
+ }
+
+ for (int i = -1; i <= 1; i += 2) {
+ int np1X = now.p1.x + i;
+ int np1Y = now.p1.y;
+ int np2X = now.p2.x + i;
+ int np2Y = now.p2.y;
+
+ if (check(np1X, np1Y) && check(np2X, np2Y)) {
+ if (rotate(np1X, np1Y, now.p1.x, now.p1.y) && (!col[np1X][np1Y] || !col[now.p1.x][now.p1.y])) {
+ col[np1X][np1Y] = true;
+ col[now.p1.x][now.p1.y] = true;
+ q.add(new Robot(new Point(np1X, np1Y), new Point(now.p1.x, now.p1.y), 1));
+ }
+ if (rotate(np2X, np2Y, now.p2.x, now.p2.y) && (!col[np2X][np2Y] || !col[now.p2.x][now.p2.y])) {
+ col[np2X][np2Y] = true;
+ col[now.p2.x][now.p2.y] = true;
+ q.add(new Robot(new Point(np2X, np2Y), new Point(now.p2.x, now.p2.y), 1));
+ }
+ }
+ }
+ } else {
+ for (int i = 0; i < 4; i++) {
+ int np1X = now.p1.x + dx[i];
+ int np1Y = now.p1.y + dy[i];
+ int np2X = now.p2.x + dx[i];
+ int np2Y = now.p2.y + dy[i];
+
+ if (check(np1X, np1Y) && check(np2X, np2Y)) {
+ if (!col[np1X][np1Y] || !col[np2X][np2Y]) {
+ Robot next = new Robot(new Point(np1X, np1Y), new Point(np2X, np2Y), 1);
+ col[np1X][np1Y] = true;
+ col[np2X][np2Y] = true;
+ q.add(next);
+ }
+ }
+ }
+
+ for (int i = -1; i <= 1; i += 2) {
+ int np1X = now.p1.x;
+ int np1Y = now.p1.y + i;
+ int np2X = now.p2.x;
+ int np2Y = now.p2.y + i;
+
+ if (check(np1X, np1Y) && check(np2X, np2Y)) {
+ if (rotate(np1X, np1Y, now.p1.x, now.p1.y) && (!row[np1X][np1Y] || !row[now.p1.x][now.p1.y])) {
+ row[np1X][np1Y] = true;
+ row[now.p1.x][now.p1.y] = true;
+ q.add(new Robot(new Point(np1X, np1Y), new Point(now.p1.x, now.p1.y), 0));
+ }
+ if (rotate(np2X, np2Y, now.p2.x, now.p2.y) && (!row[np2X][np2Y] || !row[now.p2.x][now.p2.y])) {
+ row[np2X][np2Y] = true;
+ row[now.p2.x][now.p2.y] = true;
+ q.add(new Robot(new Point(np2X, np2Y), new Point(now.p2.x, now.p2.y), 0));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public boolean rotate(int x1, int y1, int x2, int y2) {
+ if (!check(x1, y1) || !check(x2, y2)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean check(int x, int y) {
+ return x >= 0 && y >= 0 && x < n && y < n && map[x][y] == 0;
+ }
+
+ class Robot {
+
+ Point p1, p2;
+ int dir;
+
+ Robot(Point p1, Point p2, int dir) {
+ this.p1 = p1;
+ this.p2 = p2;
+ this.dir = dir;
+ }
+ }
+
+ class Point {
+
+ int x, y;
+
+ Point(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+ }
+}
diff --git a/eonju/PMS/PMS_72413.java b/eonju/PMS/PMS_72413.java
new file mode 100644
index 0000000..d7118dd
--- /dev/null
+++ b/eonju/PMS/PMS_72413.java
@@ -0,0 +1,85 @@
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.PriorityQueue;
+
+public class Solution {
+
+ private static HashMap> graph;
+
+ public static void main(String[] args) {
+ solution(7, 4, 3, 1, new int[][]{{5, 7, 9}, {4, 6, 4}, {3, 6, 1}, {3, 2, 3}, {2, 1, 6}});
+ }
+
+ public static int solution(int n, int s, int a, int b, int[][] fares) {
+ graph = new HashMap<>();
+ for (int i = 1; i <= n; i++) {
+ graph.put(i, new ArrayList<>());
+ }
+
+ for (int i = 0; i < fares.length; i++) {
+ int[] fare = fares[i];
+
+ graph.get(fare[0]).add(new Edge(fare[1], fare[2]));
+ graph.get(fare[1]).add(new Edge(fare[0], fare[2]));
+ }
+
+ int[] distA = new int[n + 1];
+ Arrays.fill(distA, Integer.MAX_VALUE);
+
+ int[] distB = new int[n + 1];
+ Arrays.fill(distB, Integer.MAX_VALUE);
+
+ int[] distS = new int[n + 1];
+ Arrays.fill(distS, Integer.MAX_VALUE);
+
+ dijkstra(distA, a);
+ dijkstra(distB, b);
+ dijkstra(distS, s);
+
+ int min = distA[s] + distB[s];
+ for (int i = 1; i <= n; i++) {
+ if (min > distA[i] + distB[i] + distS[i]) {
+ min = distA[i] + distB[i] + distS[i];
+ }
+ }
+
+ return min;
+ }
+
+ public static void dijkstra(int[] dist, int start) {
+ PriorityQueue queue = new PriorityQueue<>(Comparator.comparing(x -> x.weight));
+ queue.add(new Edge(start, 0));
+ dist[start] = 0;
+
+ while (!queue.isEmpty()) {
+ Edge poll = queue.poll();
+ if (poll.weight > dist[poll.end]) {
+ continue;
+ }
+
+ for (Edge edge : graph.get(poll.end)) {
+ if (edge.weight + poll.weight < dist[edge.end]) {
+ dist[edge.end] = edge.weight + poll.weight;
+ queue.add(new Edge(edge.end, dist[edge.end]));
+ }
+ }
+ }
+
+ }
+
+
+ static class Edge {
+
+ int end;
+ int weight;
+
+ public Edge(int end, int weight) {
+ this.end = end;
+ this.weight = weight;
+ }
+ }
+
+}
diff --git a/eonju/PMS/PMS_72415.java b/eonju/PMS/PMS_72415.java
new file mode 100644
index 0000000..5d9b9e5
--- /dev/null
+++ b/eonju/PMS/PMS_72415.java
@@ -0,0 +1,97 @@
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+class Solution {
+
+ private static Location now;
+ private static HashMap> cards;
+
+ public static void main(String[] args) {
+ System.out.println(solution(new int[][]{{1, 0, 0, 3}, {2, 0, 0, 0}, {0, 0, 0, 2}, {3, 0, 1, 0}}, 1, 0));
+ System.out.println(solution(new int[][]{{3, 0, 0, 2}, {0, 0, 1, 0}, {0, 1, 0, 0}, {2, 0, 0, 3}}, 0, 1));
+ }
+
+ public static int solution(int[][] board, int r, int c) {
+ now = new Location(r, c);
+ cards = new HashMap<>();
+
+ for (int i = 0; i < board.length; i++) {
+ for (int j = 0; j < board[i].length; j++) {
+ if (board[i][j] != 0) {
+ cards.putIfAbsent(board[i][j], new LinkedList<>());
+ cards.get(board[i][j]).add(new Location(i, j));
+ }
+ }
+ }
+
+ int answer = 0;
+
+ while (!cards.isEmpty()) {
+ Location target = findMinDist();
+
+ int number = board[target.height][target.width];
+ List locations = cards.get(number);
+
+ int dist = 0;
+ Location tmp = null;
+
+ for (Location location : locations) {
+ if (location.height == target.height && location.width == target.width) {
+ if (location.height == now.height || location.width == now.width) {
+ dist += 1;
+ } else {
+ dist += Math.abs(now.height - location.height) + Math.abs(now.width - location.width);
+ }
+ } else {
+ if (location.height == target.height || location.width == target.width) {
+ dist += 1;
+ tmp = new Location(location.height, location.width);
+ } else {
+ dist += Math.abs(target.height - location.height) + Math.abs(target.width - location.width);
+ tmp = new Location(location.height, location.width);
+ }
+ }
+ }
+ cards.remove(number);
+ answer += (dist + 2);
+ now = tmp;
+ }
+
+ return answer;
+ }
+
+ public static Location findMinDist() {
+ int minValue = Integer.MAX_VALUE;
+ Location minLocation = null;
+
+ for (Integer number : cards.keySet()) {
+ for (Location location : cards.get(number)) {
+ if (location.height == now.height || location.width == now.width) {
+ minValue = 1;
+ minLocation = location;
+ } else {
+ int dist = Math.abs(now.height - location.height) + Math.abs(now.width - location.width);
+ if (minValue > dist) {
+ minLocation = location;
+ minValue = dist;
+ }
+ }
+ }
+ }
+
+ return minLocation;
+ }
+
+
+ static class Location {
+
+ int height;
+ int width;
+
+ public Location(int height, int width) {
+ this.height = height;
+ this.width = width;
+ }
+ }
+}
diff --git a/eonju/PMS/PMS_81304.java b/eonju/PMS/PMS_81304.java
new file mode 100644
index 0000000..f5896ce
--- /dev/null
+++ b/eonju/PMS/PMS_81304.java
@@ -0,0 +1,146 @@
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.PriorityQueue;
+import java.util.Queue;
+
+class Solution {
+
+ static int INF = Integer.MAX_VALUE;
+ static int[][] dist;
+ static List[] list, rList;
+ static Map trapList;
+
+ public int solution(int n, int start, int end, int[][] roads, int[] traps) {
+ list = new ArrayList[n + 1];
+ rList = new ArrayList[n + 1];
+
+ for (int i = 1; i < n + 1; i++) {
+ list[i] = new ArrayList<>();
+ rList[i] = new ArrayList<>();
+ }
+
+ trapList = new HashMap<>();
+ for (int i = 0; i < traps.length; i++) {
+ trapList.put(traps[i], 1 << (i + 1));
+ }
+
+ for (int i = 0; i < roads.length; i++) {
+ int from = roads[i][0];
+ int to = roads[i][1];
+ int w = roads[i][2];
+
+ list[from].add(new Node(to, w, 0));
+ rList[to].add(new Node(from, w, 0));
+ }
+
+ int len = 1 << 11;
+ dist = new int[n + 1][len];
+ for (int i = 1; i < n + 1; i++) {
+ Arrays.fill(dist[i], INF);
+ }
+
+ dijkstra(start, end);
+
+ int answer = INF;
+ for (int ca : dist[end]) {
+ answer = Math.min(answer, ca);
+ }
+ return answer;
+ }
+
+ static void dijkstra(int start, int end) {
+ Queue queue = new PriorityQueue<>();
+ dist[start][0] = 0;
+ queue.add(new Node(start, 0, 0));
+
+ while (!queue.isEmpty()) {
+ Node node = queue.poll();
+ int to = node.end;
+ int w = node.weight;
+ int status = node.status;
+
+ if (to == end) {
+ return;
+ }
+
+ // f1 (pos node) ? trap o : (trap x 또는 일반)
+ boolean f1 = false;
+ if (trapList.containsKey(to)) {
+ if ((status & trapList.get(to)) == trapList.get(to)) {
+ f1 = true;
+ }
+ }
+
+ // 정방향 (tt, ff)
+ // f2(nxt node) ? trap o : (trap x 또는 일반)
+ boolean f2 = false;
+ for (Node nxt : list[to]) {
+ int nStatus = status;
+ if (trapList.containsKey(nxt.end)) {
+ f2 = ((status & trapList.get(nxt.end)) != 0);
+ nStatus = trapSwitch(f2, status, trapList.get(nxt.end));
+
+ if (f1 & f2 || (!f1 & !f2)) { // (!f1^f2)
+ if (dist[nxt.end][status] > w + nxt.weight) {
+ dist[nxt.end][status] = w + nxt.weight;
+ queue.add(new Node(nxt.end, dist[nxt.end][status], nStatus));
+ }
+ }
+ } else {
+ if (!f1) {
+ if (dist[nxt.end][status] > w + nxt.weight) {
+ dist[nxt.end][status] = w + nxt.weight;
+ queue.add(new Node(nxt.end, dist[nxt.end][status], nStatus));
+ }
+ }
+ }
+ }
+
+ // 역방향 (tf, ft)
+ // f2(nxt node) ? trap o : (trap x 또는 일반)
+ f2 = false;
+ for (Node nxt : rList[to]) {
+ int nStatus = status;
+ if (trapList.containsKey(nxt.end)) {
+ f2 = ((status & trapList.get(nxt.end)) != 0);
+ nStatus = trapSwitch(f2, status, trapList.get(nxt.end));
+ }
+ if (f1 ^ f2) {
+ if (dist[nxt.end][status] > w + nxt.weight) {
+ dist[nxt.end][status] = w + nxt.weight;
+ queue.add(new Node(nxt.end, dist[nxt.end][status], nStatus));
+ }
+ }
+ }
+ }
+ }
+
+ static int trapSwitch(boolean flag, int now, int node) {
+ if (flag) { // 다음 노드가 trap인데 활성화 되어있는 경우
+ return now ^ node;
+ } else { // 다음 노드가 trap인데 활성화 되어있지 않은 경우
+ return now | node;
+ }
+ }
+
+ static class Node implements Comparable {
+
+ int end;
+ int weight;
+ int status;
+
+ public Node(int end, int weight, int status) {
+ this.end = end;
+ this.weight = weight;
+ this.status = status;
+ }
+
+ @Override
+ public int compareTo(Node o) {
+ return this.weight - o.weight;
+ }
+ }
+}
diff --git a/eonju/PMS/PMS_81305.java b/eonju/PMS/PMS_81305.java
new file mode 100644
index 0000000..a4e3cc0
--- /dev/null
+++ b/eonju/PMS/PMS_81305.java
@@ -0,0 +1,50 @@
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+class Solution {
+
+ private static HashMap> graph;
+ private static int root;
+
+ public int solution(int k, int[] num, int[][] links) {
+ graph = new HashMap<>();
+ }
+
+ public static int dfs(){
+
+ }
+
+ public static void makeGraph(int[][] links) {
+ for (int i = 0; i < links.length; i++) {
+ int[] link = links[i];
+
+ int left = link[0];
+ int right = link[1];
+
+ graph.put(i, new ArrayList<>());
+ if (left != -1) {
+ graph.get(i).add(left);
+ }
+ if (right != -1) {
+ graph.get(i).add(right);
+ }
+
+ }
+ }
+
+ static class Node {
+
+ int number;
+ int left;
+ int right;
+ int leftSum;
+ int rightSum;
+
+ public Node(int number, int left, int right) {
+ this.number = number;
+ this.left = left;
+ this.right = right;
+ }
+ }
+}
diff --git "a/sunH0/week16/Pms_\353\257\270\353\241\234\355\203\210\354\266\234.java" "b/sunH0/week16/Pms_\353\257\270\353\241\234\355\203\210\354\266\234.java"
new file mode 100644
index 0000000..1b2cffe
--- /dev/null
+++ "b/sunH0/week16/Pms_\353\257\270\353\241\234\355\203\210\354\266\234.java"
@@ -0,0 +1,106 @@
+package kakao;
+
+import java.util.*;
+
+public class Pms_미로탈출 {
+ public int solution(int n, int start, int end, int[][] roads, int[] traps) {
+ int[][] graph = new int[n + 1][n + 1];
+
+ for(int i = 0; i < graph.length; i++){
+ Arrays.fill(graph[i],3001);
+ }
+
+
+ for (int[] road : roads) {
+ graph[road[0]][road[1]] = Math.min(graph[road[0]][road[1]], road[2]);
+ }
+
+ boolean[][] visited = new boolean[n + 1][1 << traps.length];
+
+ Queue queue = new PriorityQueue<>();
+ queue.add(new Node(start, 0, 0));
+
+ while (!queue.isEmpty()) {
+ Node current = queue.poll();
+ int state = current.state;
+
+ if (current.number == end) {
+ return current.cost;
+ }
+
+ if (visited[current.number][current.state]) {
+ continue;
+ }
+ visited[current.number][current.state] = true;
+
+ boolean currentTrapped = false;
+ Set trapped = new HashSet<>();
+
+ //현재 노드 트랩처리
+ for (int i = 0; i < traps.length; i++) {
+ int bit = 1 << i;
+
+ if ((state & bit) != 0) {
+ if (current.number == traps[i]) {
+ state &= ~bit; // state에서 이 trap을 비활성화
+ continue;
+ }
+
+ trapped.add(traps[i]);
+ continue;
+ }
+
+ if (current.number == traps[i]) {
+ state |= bit;
+ trapped.add(traps[i]);
+ currentTrapped = true;
+ }
+ }
+
+ for (int i = 1; i <= n; i++) {
+ if (current.number == i) {
+ continue;
+ }
+
+ boolean nextTrapped = trapped.contains(i); // 다음 이동할 노드가 trap인지 체크
+
+ if (currentTrapped == nextTrapped) {
+ if (graph[current.number][i] != 3001) {
+ queue.add(new Node(i, current.cost + graph[current.number][i], state));
+ }
+ continue;
+ }
+
+ // 둘 중 하나가 트랩이라면 그래프의 역방향을 적용
+ if (graph[i][current.number] != 3001) {
+ queue.add(new Node(i, current.cost + graph[i][current.number], state));
+ }
+ }
+
+
+ }
+
+ return 3001;
+}
+}
+class Node implements Comparable {
+ int number;
+ int cost;
+ int state;
+
+ public Node(int number, int cost, int state) {
+ this.number = number;
+ this.cost = cost;
+ this.state = state;
+ }
+
+ @Override
+ public int compareTo(Node o) {
+ return this.cost - o.cost;
+ }
+}
+
+
+
+
+
diff --git "a/sunH0/week16/Pms_\354\210\253\354\236\220\353\254\270\354\236\220\354\227\264\352\263\274\354\230\201\353\213\250\354\226\264.java" "b/sunH0/week16/Pms_\354\210\253\354\236\220\353\254\270\354\236\220\354\227\264\352\263\274\354\230\201\353\213\250\354\226\264.java"
new file mode 100644
index 0000000..7538e17
--- /dev/null
+++ "b/sunH0/week16/Pms_\354\210\253\354\236\220\353\254\270\354\236\220\354\227\264\352\263\274\354\230\201\353\213\250\354\226\264.java"
@@ -0,0 +1,11 @@
+class Solution {
+ public int solution(String s) {
+ String[] words = new String[]{"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
+
+ for (int i = 0; i < 10; i++) {
+ s = s.replace(words[i], String.valueOf(i));
+ }
+
+ return Integer.parseInt(s);
+ }
+}
diff --git "a/sunH0/week18/Boj14630_\353\263\200\354\213\240\353\241\234\353\264\207.java" "b/sunH0/week18/Boj14630_\353\263\200\354\213\240\353\241\234\353\264\207.java"
new file mode 100644
index 0000000..6ef2b97
--- /dev/null
+++ "b/sunH0/week18/Boj14630_\353\263\200\354\213\240\353\241\234\353\264\207.java"
@@ -0,0 +1,86 @@
+package dijkstra;
+
+import java.util.*;
+import java.io.*;
+
+public class Boj14630_변신로봇 {
+
+ static int start,end,N;
+ static PriorityQueue pq;
+ static String[] arr;
+ static boolean[] visited;
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ N = Integer.parseInt(br.readLine());
+
+ arr = new String[N+1];
+ for(int i=1;i<=N;i++){
+ arr[i] = br.readLine();
+ }
+
+ StringTokenizer st = new StringTokenizer(br.readLine());
+ start = Integer.parseInt(st.nextToken());
+ end = Integer.parseInt(st.nextToken());
+ visited = new boolean[N+1];
+
+
+ dijk();
+
+ }
+
+ static void dijk() {
+
+ pq = new PriorityQueue((Node a,Node b) -> a.w-b.w);
+ pq.add(new Node(start,0));
+
+ while(!pq.isEmpty()){
+ Node now = pq.poll();
+ int idx = now.idx;
+
+ if(idx==end){
+ System.out.println(now.w);
+ return;
+ }
+
+ if(visited[idx]) continue;
+ visited[idx] = true;
+
+ for(int i=1;i<=N;i++){
+ if(idx!=i){
+ pq.add(new Node(i,now.w+getCost(arr[idx], arr[i])));
+ }
+ }
+
+ }
+
+
+ }
+
+ public static int getCost(String a , String b){
+ int sum = 0 ;
+ for(int i=0;i pq;
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ N = Integer.parseInt(br.readLine());
+ E = Integer.parseInt(br.readLine());
+
+ parent = new int[N+1];
+ for (int i = 1; i <= N; i++) {
+ parent[i] = i;
+ }
+
+ pq = new PriorityQueue<>();
+
+ for (int i=0; i< E; i++){
+ StringTokenizer st = new StringTokenizer(br.readLine());
+ int from = Integer.parseInt(st.nextToken());
+ int to = Integer.parseInt(st.nextToken());
+ int weight = Integer.parseInt(st.nextToken());
+
+ pq.add(new Node(from, to, weight));
+ }
+
+ int total =0;
+
+ while(!pq.isEmpty()){
+ Node node = pq.poll();
+
+ if(union(node.a,node.b)) total += node.w;
+
+ }
+ System.out.println(total);
+
+ }
+
+ static int find(int a){
+ if(a==parent[a]) return a;
+
+ parent[a] = find(parent[a]);
+ return parent[a];
+ }
+
+ static boolean union(int a, int b){
+ int x = find(a);
+ int y = find(b);
+
+ if(x==y) return false;
+
+ // if(x < y) parent[y] = x;
+ // else parent[x] = y;
+
+ parent[y]=x;
+ return true;
+ }
+
+
+ static class Node implements Comparable{
+ int a;
+ int b;
+ int w;
+ public Node(int a, int b, int w){
+ this.a = a;
+ this.b = b;
+ this.w = w;
+ }
+
+ @Override
+ public int compareTo(Node o) {
+ return o.w >= this.w ? -1 : 1;
+ }
+ }
+
+}
diff --git "a/sunH0/week18/Boj3151_\355\225\251\354\235\2640.java" "b/sunH0/week18/Boj3151_\355\225\251\354\235\2640.java"
new file mode 100644
index 0000000..5465232
--- /dev/null
+++ "b/sunH0/week18/Boj3151_\355\225\251\354\235\2640.java"
@@ -0,0 +1,71 @@
+package 투포인터;
+
+import java.io.*;
+import java.util.*;
+
+public class Boj3151_합이0 {
+
+ public static void main(String[] args) throws IOException {
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ StringTokenizer st = new StringTokenizer(br.readLine());
+
+ int N = Integer.parseInt(st.nextToken());
+ int[] arr = new int[N];
+
+ st = new StringTokenizer(br.readLine());
+ for (int i = 0; i < N; i++) {
+ arr[i] = Integer.parseInt(st.nextToken());
+ }
+
+ Arrays.sort(arr);
+
+ long cnt= 0;
+ int start,end,fix;
+
+ for(int i=0;i0) break;
+
+ fix = arr[i];
+ start = i+1;
+ end = N-1;
+
+ while(start0) end--;
+ }
+
+ }
+
+ System.out.println(cnt);
+
+ }
+
+ static int comb(int n){
+ return n*(n-1)/2;
+ }
+}
diff --git "a/sunH0/week19/Boj1963_\354\206\214\354\210\230\352\262\275\353\241\234.java" "b/sunH0/week19/Boj1963_\354\206\214\354\210\230\352\262\275\353\241\234.java"
new file mode 100644
index 0000000..7c07960
--- /dev/null
+++ "b/sunH0/week19/Boj1963_\354\206\214\354\210\230\352\262\275\353\241\234.java"
@@ -0,0 +1,100 @@
+package 소수;
+
+import java.io.*;
+import java.util.*;
+
+public class Boj1963_소수경로 {
+
+ static boolean[] isPrime = new boolean[100001];
+
+ public static void main(String[] args) throws IOException{
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ StringTokenizer st;
+ int t = Integer.parseInt(br.readLine());
+ checkPrime();
+
+ for(int i=0; i q = new LinkedList<>();
+ Set set = new HashSet<>();
+
+ set.add(now);
+ q.add(new Prime(now, 0));
+
+ while(!q.isEmpty()) {
+ Prime prime = q.poll();
+
+ int[] pNum = {prime.num/1000, (prime.num/100)%10, (prime.num/10)%10, prime.num%10};
+
+ if(prime.num == target) {
+ return prime.cnt;
+ }
+
+ for(int i=0; i<4; i++) {
+ for(int j=0; j<10; j++) {
+ if(i==0 && j==0) continue;
+
+ int tmp = pNum[i];
+ pNum[i] = j;
+ int next = changePassword(pNum);
+ pNum[i] = tmp;
+
+ if(isPrime[next]) continue;
+ if(!set.contains(next)) {
+ q.add(new Prime(next, prime.cnt+1));
+ set.add(next);
+ }
+ }
+ }
+
+ }
+
+ return -1;
+ }
+
+ static void checkPrime() {
+ for(int i=2; i<10000; i++) {
+ if(!isPrime[i]) {
+ for(int j=i*i; j<10000; j+=i) {
+ isPrime[j] = true;
+ }
+ }
+
+ }
+ }
+
+ static int changePassword(int[] pNum) {
+ int num =0;
+ for(int i=0; i<4; i++) {
+ num += pNum[i]*(Math.pow(10, 3-i));
+ }
+ return num;
+
+ }
+
+ static class Prime{
+ int num;
+ int cnt;
+
+ public Prime(int num, int cnt) {
+ this.num = num;
+ this.cnt = cnt;
+ }
+
+
+ }
+
+
+}
diff --git "a/sunH0/week19/Boj22352_\355\225\255\354\262\264\354\235\270\354\213\235.java" "b/sunH0/week19/Boj22352_\355\225\255\354\262\264\354\235\270\354\213\235.java"
new file mode 100644
index 0000000..b7b2d48
--- /dev/null
+++ "b/sunH0/week19/Boj22352_\355\225\255\354\262\264\354\235\270\354\213\235.java"
@@ -0,0 +1,112 @@
+package 완전탐색;
+
+import java.io.*;
+import java.util.*;
+
+public class Boj22352_항체인식 {
+
+ static int N, M;
+ static int[][] bMap;
+ static int[][] aMap;
+
+ static int[] dx = {1,-1,0,0};
+ static int[] dy = {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());
+
+ N = Integer.parseInt(st.nextToken());
+ M = Integer.parseInt(st.nextToken());
+
+ bMap = new int[N][M];
+ aMap = new int[N][M];
+
+ for(int i=0; i q = new LinkedList<>();
+ boolean[][] visited = new boolean[N][M];
+
+ q.add(new Node(x,y));
+ visited[x][y] = true;
+
+ while(!q.isEmpty()){
+
+ Node now = q.poll();
+
+ for(int i=0; i<4; i++){
+ int nx = now.x + dx[i];
+ int ny = now.y + dy[i];
+
+ if (nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
+
+ if(!visited[nx][ny]&&bMap[nx][ny]==bMap[x][y]){
+ q.add(new Node(nx,ny));
+ visited[nx][ny] = true;
+ bMap[nx][ny] = val;
+ }
+ }
+
+ }
+ bMap[x][y] = val;
+ }
+
+ static boolean validCPCU(){
+
+ for(int x=0; x= 0 && ny >= 0 && nx < N && ny < M) {
+ if(map[nx][ny] != 0 && !visited[nx][ny]) {
+ dfs(nx, ny);
+ }
+ }
+ }
+
+ }
+
+ public static void melting() {
+
+ boolean[][] temp = new boolean[N][M];
+
+ for(int i = 0; i < N; i++) {
+ for(int j = 0; j < M; j++) {
+ if(map[i][j] != 0) {
+ temp[i][j] = true;
+ int cnt = 0;
+
+ for(int k = 0; k < 4; k++) {
+ int nx = i + dx[k];
+ int ny = j + dy[k];
+ if(nx >= 0 && ny >= 0 && nx < N && ny < M) {
+ if(!temp[nx][ny] && map[nx][ny] == 0) cnt++;
+ }
+
+ }
+ if(map[i][j] < cnt) map[i][j] = 0;
+ else map[i][j] -= cnt;
+ }
+
+ }
+ }
+
+ }
+
+ public static void main(String[] args) throws Exception{
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ StringTokenizer st= new StringTokenizer(br.readLine());
+
+ N = Integer.parseInt(st.nextToken());
+ M = Integer.parseInt(st.nextToken());
+ map = new int[N][M];
+
+ for(int i=0; i= 2) break;
+ else if(iceCnt==0) {
+ ans=0;
+ break;
+ }
+
+ melting();
+ ans++;
+ }
+
+ System.out.println(ans);
+ }
+
+}
diff --git "a/sunH0/week21/Boj1253_\354\242\213\353\213\244.java" "b/sunH0/week21/Boj1253_\354\242\213\353\213\244.java"
new file mode 100644
index 0000000..2edcd43
--- /dev/null
+++ "b/sunH0/week21/Boj1253_\354\242\213\353\213\244.java"
@@ -0,0 +1,50 @@
+package 투포인터;
+
+import java.util.*;
+import java.io.*;
+
+public class Boj1253_좋다 {
+ static int N;
+ static int[] nums;
+ public static void main(String[] args) throws IOException {
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ StringTokenizer st = new StringTokenizer(br.readLine());
+
+ N = Integer.parseInt(st.nextToken());
+ nums = new int[N];
+
+ st = new StringTokenizer(br.readLine());
+ for(int i=0; i=0; i--){
+ int start = 0;
+ int end = N-1;
+
+ while(startnums[i]) end--;
+ else start++;
+ }
+
+ }
+
+
+ System.out.println(cnt);
+
+
+ }
+
+}
diff --git "a/sunH0/week21/Boj17090_\353\257\270\353\241\234\355\203\210\354\266\234\355\225\230\352\270\260.java" "b/sunH0/week21/Boj17090_\353\257\270\353\241\234\355\203\210\354\266\234\355\225\230\352\270\260.java"
new file mode 100644
index 0000000..c2f6bc1
--- /dev/null
+++ "b/sunH0/week21/Boj17090_\353\257\270\353\241\234\355\203\210\354\266\234\355\225\230\352\270\260.java"
@@ -0,0 +1,77 @@
+package DP;
+
+import java.util.*;
+import java.io.*;
+
+public class Boj17090_미로탈출하기 {
+
+ static int N,M;
+ static char[][] map;
+ static boolean[][] visited;
+ static int ans=0;
+ public static void main(String[] args) throws IOException {
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ StringTokenizer st = new StringTokenizer(br.readLine());
+
+ N = Integer.parseInt(st.nextToken());
+ M = Integer.parseInt(st.nextToken());
+ visited = new boolean[N][M];
+ map = new char[N][M];
+
+ for(int i=0; i=N || r<0 || c>=M || c<0) {
+ return true;
+ }
+
+ if(map[r][c]=='S'){
+ return true;
+ }
+
+ if(map[r][c]=='F'){
+ return false;
+ }
+
+ if(visited[r][c]){
+ return false;
+ }
+
+ visited[r][c] = true;
+ char word = map[r][c];
+
+ switch(word) {
+ case 'U': result = dfs(r-1,c); break;
+ case 'D': result = dfs(r+1,c); break;
+ case 'R': result = dfs(r,c+1); break;
+ case 'L': result = dfs(r,c-1); break;
+ }
+
+ map[r][c] = result? 'S':'F';
+
+ return result;
+ }
+
+}
+
+
+
+
diff --git "a/sunH0/week21/Boj1780_\354\242\205\354\235\264\354\235\230\352\260\234\354\210\230.java" "b/sunH0/week21/Boj1780_\354\242\205\354\235\264\354\235\230\352\260\234\354\210\230.java"
new file mode 100644
index 0000000..f77a64b
--- /dev/null
+++ "b/sunH0/week21/Boj1780_\354\242\205\354\235\264\354\235\230\352\260\234\354\210\230.java"
@@ -0,0 +1,61 @@
+package 분할정복;
+
+import java.util.*;
+import java.io.*;
+
+public class Boj1780_종이의개수 {
+
+ static int N;
+ static int[][] board;
+ static int ans[] = new int[3];
+
+ public static void main(String[] args) throws IOException {
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ StringTokenizer st = new StringTokenizer(br.readLine());
+
+ N = Integer.parseInt(st.nextToken());
+ board = new int[N][N];
+
+ for (int i = 0; i < N; i++) {
+ st = new StringTokenizer(br.readLine());
+ for (int j = 0; j < N; j++) {
+ board[i][j] = Integer.parseInt(st.nextToken());
+ }
+ }
+
+ partition(0, 0, N);
+
+ for(int i=0;i<3;i++){
+ System.out.println(ans[i]);
+ }
+
+ }
+
+ static void partition(int row, int col, int size){
+ if(check(row, col, size)){
+ ans[board[row][col]+1] += 1;
+
+ return;
+ }
+
+ for(int i=row; i userLogs = new ArrayList<>();
+ Map map = new HashMap<>();
+
+ for (String str : record) {
+ String[] arr = str.split(" ");
+
+ if(!arr[0].equals("Leave")){
+
+ if(map.containsKey(arr[1])) {
+ map.replace(arr[1], arr[2]);
+ }else{
+ map.put(arr[1], arr[2]);
+ }
+ }
+
+ if(arr[0].equals("Change")) continue;
+
+ userLogs.add(new UserLog(arr[1], LogState.valueOf(arr[0])));
+ }
+
+ String[] answer = new String[userLogs.size()];
+
+ for(int i=0;i map = new TreeMap<>();
+ static int N;
+
+ public static int[][] solution(int n, int[][] build_frame) {
+
+ N=n;
+ int cnt=0;
+
+ for(int[] frame: build_frame){
+ int x = frame[0];
+ int y = frame[1];
+ int type = frame[2];
+ int action = frame[3];
+
+ if(action == 1){
+ if(type==0 && checkPillar(x, y)){
+ map.put(getKey(x, y),0);
+ cnt++;
+ }
+ else if(type==1 && checkBeam(x, y)){
+ map.put(getKey(x, y), 1);
+ cnt++;
+ }
+ }
+ else if(action == 0) {
+ map.remove(getKey(x, y));
+ cnt--;
+ if(checkDelete(x, y)==false){
+ map.put(getKey(x, y), type);
+ cnt++;
+ }
+
+ }
+
+ }
+
+ int[][] answer = new int[cnt][3];
+ int idx=0;
+
+ for(int key : map.keySet()){
+ int[] node = getNode(key);
+ answer[idx][0] = node[0];
+ answer[idx][1] = node[1];
+ answer[idx++][2] = map.get(key);
+
+ }
+
+ return answer;
+ }
+
+ public static void main(String[] args) {
+ int[][] record = {{1,0,0,1},{1,1,1,1},{2,1,0,1},{2,2,1,1},{5,0,0,1},{5,1,0,1},{4,2,1,1},{3,2,1,1}};
+ solution(5,record);
+ }
+
+ public static int getKey(int x, int y){
+
+ return x * N + y;
+ }
+
+ public static int[] getNode(int key){
+
+ int[] arr = new int[2];
+ arr[0] = key / N;
+ arr[1] = key % N;
+
+ return arr;
+ }
+
+ public static boolean checkDelete(int x, int y){
+
+ for(int key : map.keySet()){
+ int type = map.get(key);
+ int arr[] = getNode(key);
+
+ if(type==0&&checkPillar(arr[0], arr[1])==false) return false;
+ else if(type==1 && checkBeam(arr[0], arr[1])==false) return false;
+ }
+ return true;
+
+ }
+
+ public static boolean checkBeam(int x, int y) {
+ if(y>0 && map.getOrDefault(getKey(x,y-1),-1)==0||map.getOrDefault(getKey(x+1, y-1),-1)==0) return true;
+ else if(x>0 && map.getOrDefault(getKey(x-1,y), -1)==1 && map.getOrDefault(getKey(x+1,y), -1) == 1) return true;
+ else return false;
+ }
+
+ public static boolean checkPillar(int x, int y){
+
+ if(y==0) return true;
+ else if(map.getOrDefault(getKey(x,y-1), -1) == 0 ) return true;
+ else if(x>0 && map.getOrDefault(getKey(x-1,y),-1) == 1 || map.getOrDefault(getKey(x,y),-1)==1) return true;
+ else return false;
+
+ }
+*/
+
diff --git "a/sunH0/\353\252\250\354\235\230\354\275\224\355\205\214/Practice3.java" "b/sunH0/\353\252\250\354\235\230\354\275\224\355\205\214/Practice3.java"
new file mode 100644
index 0000000..75db787
--- /dev/null
+++ "b/sunH0/\353\252\250\354\235\230\354\275\224\355\205\214/Practice3.java"
@@ -0,0 +1,90 @@
+package 기타;
+
+import java.util.*;
+
+class Practice3 {
+ class Item{
+ int x1, x2, y1, y2, time, vertical;
+ Item(int x1, int y1, int x2, int y2, int time, int v){
+ this.x1 = x1;
+ this.y1 = y1;
+ this.x2 = x2;
+ this.y2 = y2;
+ this.time = time;
+ this.vertical = v;
+ }
+ }
+
+ public int solution(int[][] board) {
+ int answer = 0;
+ Queue- q = new LinkedList<>();
+ int[][] op = {{1,0},{-1,0},{0,1},{0,-1}};
+ boolean[][][] visited = new boolean[board.length][board.length][2];
+
+ q.offer(new Item(0, 0, 0, 1, 0, 0));
+
+ while(!q.isEmpty()){
+ Item item = q.peek();
+ q.poll();
+
+ if(item.x1 < 0 || item.x1 >= board.length || item.y1 < 0 || item.y1 >= board.length ||
+ item.x2 < 0 || item.x2 >= board.length || item.y2 < 0 || item.y2 >= board.length){
+ continue;
+ }
+
+ if(board[item.x1][item.y1] == 1 || board[item.x2][item.y2] == 1){
+ continue;
+ }
+
+ if(visited[item.x1][item.y1][item.vertical] &&
+ visited[item.x2][item.y2][item.vertical])
+ continue;
+
+ if((item.x1 == board.length - 1 && item.y1 == board.length - 1) ||
+ (item.x2 == board.length - 1 && item.y2 == board.length - 1)){
+ answer = item.time;
+ break;
+ }
+
+
+ visited[item.x1][item.y1][item.vertical] = true;
+ visited[item.x2][item.y2][item.vertical] = true;
+
+ for(int i = 0; i < op.length; i++){
+ int n_x1 = item.x1 + op[i][0];
+ int n_y1 = item.y1 + op[i][1];
+ int n_x2 = item.x2 + op[i][0];
+ int n_y2 = item.y2 + op[i][1];
+
+ q.offer(new Item(n_x1, n_y1, n_x2, n_y2, item.time + 1, item.vertical));
+ }
+
+ if(item.vertical == 1){
+ if(item.y1 - 1 >= 0 && board[item.x1][item.y1 - 1] == 0 && board[item.x2][item.y2 - 1] == 0){
+ q.offer(new Item(item.x1, item.y1, item.x1, item.y1 - 1, item.time + 1, 0));
+ q.offer(new Item(item.x2, item.y2, item.x2, item.y2 - 1, item.time + 1, 0));
+ }
+
+ if(item.y1 + 1 <= (board.length - 1) &&
+ board[item.x1][item.y1 + 1] == 0 && board[item.x2][item.y2 + 1] == 0){
+ q.offer(new Item(item.x1, item.y1, item.x1, item.y1 + 1, item.time + 1, 0));
+ q.offer(new Item(item.x2, item.y2, item.x2, item.y2 + 1, item.time + 1, 0));
+ }
+ }else{
+ if(item.x1 - 1 >= 0 && board[item.x1 - 1][item.y1] == 0 &&
+ board[item.x2 - 1][item.y2] == 0){
+ q.offer(new Item(item.x1, item.y1, item.x1 - 1, item.y1, item.time + 1, 1));
+ q.offer(new Item(item.x2, item.y2, item.x2 - 1, item.y2, item.time + 1, 1));
+ }
+
+ if(item.x1 + 1 <= (board.length - 1) && board[item.x1 + 1][item.y1] == 0 &&
+ board[item.x2 + 1][item.y2] == 0){
+ q.offer(new Item(item.x1, item.y1, item.x1 + 1, item.y1, item.time + 1, 1));
+ q.offer(new Item(item.x2, item.y2, item.x2 + 1, item.y2, item.time + 1, 1));
+ }
+ }
+ }
+
+ return answer;
+ }
+}
diff --git "a/\352\271\200\354\261\204\354\233\220/week16/PG_81304.java" "b/\352\271\200\354\261\204\354\233\220/week16/PG_81304.java"
new file mode 100644
index 0000000..933b7a2
--- /dev/null
+++ "b/\352\271\200\354\261\204\354\233\220/week16/PG_81304.java"
@@ -0,0 +1,129 @@
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.lang.reflect.Array;
+import java.util.*;
+
+class Edge{
+ public int vex;
+ public int cost;
+ public int isRoad;
+
+ Edge(int vex, int cost, int isRoad) {
+ this.vex = vex;
+ this.cost = cost;
+ this.isRoad = isRoad;
+ }
+}
+
+class State implements Comparable {
+ public int vex;
+ public int cost;
+ public int state;
+
+ public State(int vex, int cost, int state) {
+ this.vex = vex;
+ this.cost = cost;
+ this.state = state;
+ }
+
+ @Override
+ public int compareTo(State ob) {
+ return this.cost - ob.cost;
+ }
+}
+
+
+class Solution {
+ static int n, m;
+ static ArrayList> graph;
+ static int d[][] = new int[1004][1<<10];
+ static int trapidx[] = new int[1004];
+
+ static boolean bitmask(int state, int node) { // 현재 상태에서 node를 방문했는지 확인
+ if(((1< pQ = new PriorityQueue<>();
+ int state = 0;
+ pQ.offer(new State(v,0,state));
+ d[v][state] = 0;
+
+ while (!pQ.isEmpty()) {
+ State tmp = pQ.poll();
+ int now = tmp.vex;
+ int nowCost = tmp.cost;
+ int nowState = tmp.state;
+ if(nowCost > d[now][nowState]) continue;
+
+ for (Edge ob : graph.get(now)) {
+ int rev = 0;
+ if(trapidx[now] != 0 && bitmask(nowState, trapidx[now]-1)) rev ^= 1; // 현재 cur.idx번 trap을 밟은 상태라면 rev 상태를 뒤집음
+ if(trapidx[ob.vex] != 0 && bitmask(nowState, trapidx[ob.vex]-1)) rev ^= 1; // 현재 nxt.x번 trap을 밟은 상태라면 rev 상태를 뒤집음
+ if(ob.isRoad != rev) continue; //갈수 없는 길은 건너뜀
+ int nextState = nowState;
+ if(trapidx[ob.vex] != 0) nextState = (nextState ^ (1< nowCost + ob.cost) {
+ d[ob.vex][nextState] = nowCost + ob.cost;
+ pQ.offer(new State(ob.vex, nowCost + ob.cost, nextState));
+ }
+ }
+ }
+ }
+
+ public int solution(int n, int start, int end, int[][] roads, int[] traps) {
+ int answer = Integer.MAX_VALUE;
+ graph = new ArrayList>();
+ for (int i = 0; i <= n; i++) {
+ graph.add(new ArrayList());
+ }
+
+ for (int i = 0; i < d.length; i++) {
+ Arrays.fill(d[i], Integer.MAX_VALUE);
+ }
+
+ for (int i = 0; i < traps.length; i++) {
+ trapidx[traps[i]] = i+1;
+ }
+
+ for (int i = 0; i < roads.length; i++) {
+ int a = roads[i][0];
+ int b = roads[i][1];
+ int vex = roads[i][2];
+
+ graph.get(a).add(new Edge(b, vex, 0));
+ if (trapidx[a] != 0 || trapidx[b] != 0) graph.get(b).add(new Edge(a, vex, 1));
+ }
+
+
+ dijkstra(start,end);
+ for (int i = 0; i < (1 << 10); i++) {
+ answer = Math.min(answer, d[end][i]);
+ }
+
+ System.out.println(answer);
+ return answer;
+ }
+
+ public static void main(String[] args) {
+ Solution T = new Solution();
+// String tstring = "this is {template} {template} is {state}";
+// String[][] variables = {{"template", "string"}, {"state", "changed"}};
+
+// int n = 3;
+// int start = 1;
+// int end = 3;
+// int roads[][] = {{1, 2, 2}, {3, 2, 3}};
+// int[] traps = {2};
+
+ int n = 4;
+ int start = 1;
+ int end = 4;
+ int roads[][] = {{1, 2, 1}, {3, 2, 1},{2,4,1}};
+ int[] traps = {2,3};
+
+ T.solution(n, start, end, roads, traps);
+
+ }
+}
diff --git "a/\352\271\200\354\261\204\354\233\220/week16/PG_81305.java" "b/\352\271\200\354\261\204\354\233\220/week16/PG_81305.java"
new file mode 100644
index 0000000..9e4604a
--- /dev/null
+++ "b/\352\271\200\354\261\204\354\233\220/week16/PG_81305.java"
@@ -0,0 +1,78 @@
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.lang.reflect.Array;
+import java.util.*;
+
+class Solution {
+ static int l[] = new int[10005]; // 왼쪽 자식 노드 번호
+ static int r[] = new int[10005]; // 오른쪽 자식 노드 번호
+ static int x[] = new int[10005]; // 시험장의 응시 인원
+ static int p[] = new int[10005]; // 부모 노드 번호
+ static int n; // 노드의 수
+ static int root; // 루트
+ static int cnt = 0;
+
+ static int dfs(int cur, int sum) {
+ int left = 0;
+ if (l[cur] != -1) left = dfs(l[cur],sum);
+ int right = 0;
+ if (r[cur] != -1) right = dfs(r[cur],sum);
+
+ if(x[cur] + left + right <= sum) return x[cur] + left + right;
+ if (x[cur] + Math.min(left, right) <= sum) {
+ cnt++;
+ return (x[cur] + Math.min(left, right));
+ }
+ cnt += 2;
+ return x[cur];
+ }
+
+ static int isDivided(int sum) {
+ cnt = 0;
+ dfs(root, sum);
+ cnt++;
+ return cnt;
+ }
+
+
+ public int solution(int k, int[] num, int[][] links) {
+ n = num.length;
+ for(int i = 0; i < n; i++) p[i] = -1;
+ for (int i = 0; i < n; i++) {
+ l[i] = links[i][0];
+ r[i] = links[i][1];
+ x[i] = num[i];
+ if(l[i]!= -1) p[l[i]] = i;
+ if(r[i]!= -1) p[r[i]] = i;
+ }
+ //루트노드 찾기
+ for (int i = 0; i < n; i++) {
+ if (p[i] == -1) {
+ root = i;
+ break;
+ }
+ }
+
+ int st = x[0];
+ for(int i = 0; i < n; i++) st = Math.max(st, x[i]);
+ int en = (int)1e8;
+ while(st < en){
+ int mid = (st+en)/2;
+ if(isDivided(mid) <= k) en = mid;
+ else st = mid+1;
+ }
+ System.out.println(st);
+ return st;
+ }
+
+
+ public static void main(String[] args) {
+ Solution T = new Solution();
+ int n = 3;
+ int[] num = {12, 30, 1, 8, 8, 6, 20, 7, 5, 10, 4, 1};
+ int[][] links = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {8, 5}, {2, 10}, {3, 0}, {6, 1}, {11, -1}, {7, 4}, {-1, -1}, {-1, -1}};
+
+ T.solution(n, num, links);
+
+ }
+}
diff --git "a/\352\271\200\354\261\204\354\233\220/week17/PG_72413.java" "b/\352\271\200\354\261\204\354\233\220/week17/PG_72413.java"
new file mode 100644
index 0000000..7e354bb
--- /dev/null
+++ "b/\352\271\200\354\261\204\354\233\220/week17/PG_72413.java"
@@ -0,0 +1,89 @@
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.lang.reflect.Array;
+
+import java.util.*;
+
+/*
+A에서 B 최단거리 구하고
+시작지점에서 A에서 B 지나온 노드들 중에서 가장 짧게 걸리는거 더해주고
+만약 A B 지나온 루트랑 겹치면 빼주기
+ */
+class Edge implements Comparable {
+ public int vex;
+ public int cost;
+
+ Edge(int vex, int cost) {
+ this.vex = vex;
+ this.cost = cost;
+ }
+
+ @Override
+ public int compareTo(Edge ob) {
+ return this.cost - ob.cost;
+ }
+}
+
+class Solution {
+ static ArrayList> graph;
+ static int[] dis;
+
+ public void solution(int v) {
+ PriorityQueue pQ = new PriorityQueue<>();
+ pQ.offer(new Edge(v, 0));
+ dis[v] = 0;
+ while (!pQ.isEmpty()) {
+ Edge tmp = pQ.poll();
+ int now = tmp.vex;
+ int nowCost = tmp.cost;
+ if (nowCost > dis[now]) continue;
+ for (Edge ob : graph.get(now)) {
+ if (dis[ob.vex] > nowCost + ob.cost) {
+ dis[ob.vex] = nowCost + ob.cost;
+ pQ.offer(new Edge(ob.vex, nowCost + ob.cost));
+ }
+ }
+ }
+ }
+
+ static void dfs(int now, int a, int b) {
+
+ for (int i = 0; i < 3; i++) { //같이 동행 / A만 / B만
+ for (Edge ob : graph.get(now)) {
+
+ }
+ }
+ }
+
+ public int solution(int n, int s, int a, int b, int[][] fares) {
+ int answer = 0;
+ graph = new ArrayList>();
+ for (int i = 0; i <= n; i++) {
+ graph.add(new ArrayList());
+ }
+ dis = new int[n + 1];
+ Arrays.fill(dis, Integer.MAX_VALUE);
+ for (int i = 0; i < fares.length; i++) {
+ int x = fares[i][0];
+ int y = fares[0][1];
+ int z = fares[0][2];
+ graph.get(x).add(new Edge(y, z));
+ }
+ return answer;
+ }
+
+
+ public static void main(String[] args) {
+ Solution T = new Solution();
+
+ int n = 6;
+ int s = 4;
+ int a = 6;
+ int b = 2;
+
+ int[][] fares = {{4, 1, 10}, {3, 5, 24}, {5, 6, 2}, {3, 1, 41}, {5, 1, 24}, {4, 6, 50}, {2, 4, 66}
+ , {2, 3, 22}, {1, 6, 25}};
+ T.solution(n, s, a, b, fares);
+
+ }
+}
diff --git "a/\352\271\200\354\261\204\354\233\220/week17/PG_72413_2.java" "b/\352\271\200\354\261\204\354\233\220/week17/PG_72413_2.java"
new file mode 100644
index 0000000..a8aa178
--- /dev/null
+++ "b/\352\271\200\354\261\204\354\233\220/week17/PG_72413_2.java"
@@ -0,0 +1,93 @@
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.lang.reflect.Array;
+
+import java.util.*;
+
+/*
+A에서 B 최단거리 구하고
+시작지점에서 A에서 B 지나온 노드들 중에서 가장 짧게 걸리는거 더해주고
+만약 A B 지나온 루트랑 겹치면 빼주기
+ */
+class Edge implements Comparable {
+ public int vex;
+ public int cost;
+
+ Edge(int vex, int cost) {
+ this.vex = vex;
+ this.cost = cost;
+ }
+
+ @Override
+ public int compareTo(Edge ob) {
+ return this.cost - ob.cost;
+ }
+}
+
+
+class Solution {
+ static int[][] arr;
+ static int N;
+ static final int INF = 9999999;
+
+ static void FolydTest() {
+ for (int k = 1; k < N; ++k) { // 경유지
+ for (int i = 1; i < N; ++i) { // 출발지
+ if (i == k) continue; // 경유지와 출발지가 같다면 패스
+ for (int j = 1; j < N; ++j) { // 도착지
+ if (j == k || i == j) continue; // 경유지와 도착지가 같거나 출발지와 도착지가 같다면 패
+ if (arr[i][k] + arr[k][j] < arr[i][j]) {
+ arr[i][j] = arr[i][k] + arr[k][j];
+ }
+ }
+ }
+ }
+ }
+
+ static int shortestDistance(int s, int a, int b) {
+ int answer = Integer.MAX_VALUE ;
+ for (int i = 1; i < N; i++) {
+ int tmp = arr[s][i] + arr[i][a] + arr[i][b];
+ answer = Math.min(answer, tmp);
+ }
+
+ return answer;
+ }
+
+ public int solution(int n, int s, int a, int b, int[][] fares) {
+ N = n+1;
+ arr = new int[n + 1][n + 1];
+ for(int i = 0; i < N; i++) Arrays.fill(arr[i], INF);
+
+ for (int i = 1; i < n + 1; i++) {
+ arr[i][i] = 0;
+ }
+
+ for (int i = 0; i < fares.length; i++) {
+ int x = fares[i][0];
+ int y = fares[i][1];
+ int z = fares[i][2];
+ arr[x][y] = z;
+ arr[y][x] = z;
+ }
+
+ FolydTest();
+ return shortestDistance(s, a, b);
+ }
+
+
+
+ public static void main(String[] args) {
+ Solution T = new Solution();
+
+ int n = 6;
+ int s = 4;
+ int a = 6;
+ int b = 2;
+
+ int[][] fares = {{4, 1, 10}, {3, 5, 24}, {5, 6, 2}, {3, 1, 41}, {5, 1, 24}, {4, 6, 50}, {2, 4, 66}
+ , {2, 3, 22}, {1, 6, 25}};
+ T.solution(n, s, a, b, fares);
+
+ }
+}
diff --git "a/\352\271\200\354\261\204\354\233\220/week17/PG_92345.java" "b/\352\271\200\354\261\204\354\233\220/week17/PG_92345.java"
new file mode 100644
index 0000000..f60ce0f
--- /dev/null
+++ "b/\352\271\200\354\261\204\354\233\220/week17/PG_92345.java"
@@ -0,0 +1,90 @@
+class Result {
+ boolean isWin;
+ int cnt;
+
+ public Result(boolean isWin, int cnt) {
+ this.isWin = isWin;
+ this.cnt = cnt;
+ }
+}
+
+class Solution {
+ static int[] dx = {-1, 1, 0, 0};
+ static int[] dy = {0, 0, -1, 1};
+ static int max = 10_000_000;
+
+ public int solution(int[][] board, int[] aloc, int[] bloc) {
+ Result result = dfs(board,aloc,bloc,1,0);
+
+ return result.cnt;
+
+ }
+
+ static Result dfs(int[][] board, int[] aloc, int[] bloc , int turn, int move) {
+
+ int ax = aloc[0];
+ int ay = aloc[1];
+
+ int bx = bloc[0];
+ int by = bloc[1];
+ System.out.println(ax + " " + ay + " / " + bx + " " + by + " / " + turn + " " + move);
+
+ // a턴이면서 a가 졌거나 b턴이면서 b가 지면,패배사
+ if((turn > 0 && board[ax][ay] == 0) || (turn < 0 && board[bx][by] == 0)){
+ return new Result(false,move);
+ }
+
+
+
+ int win = max;
+ int lose = 0;
+
+ for (int i = 0; i < 4; i++) {
+ //a 턴일때
+ System.out.println(" " + i + " : " + ax + " " + ay + " / " + bx + " " + by + " / " + turn + " " + move);
+ if (turn > 0) {
+
+ int nx = ax + dx[i];
+ int ny = ay + dy[i];
+
+ if(nx < 0 || ny < 0|| nx>= board.length || ny >=board[0].length) continue; //범위벗어남
+ if(board[nx][ny] == 0) continue; //발판이 없는경우
+ board[ax][ay] = 0;
+ Result a = dfs(board,new int[] {nx,ny}, bloc, -turn, move+1);
+ board[ax][ay] = 1;
+ if(!a.isWin){
+ win = Math.min(win,a.cnt);
+ }else{
+ lose = Math.max(lose,a.cnt);
+ }
+
+
+ } else {
+
+ int nbx = bx + dx[i];
+ int nby = by + dy[i];
+
+ if(nbx < 0 || nby < 0|| nbx>= board.length || nby >=board[0].length) continue; //범위벗어남
+ if(board[nbx][nby] == 0) continue; //발판이 없는경우
+ board[bx][by] = 0;
+ Result b = dfs(board,aloc, new int[] {nbx,nby}, -turn, move+1);
+ board[bx][by] = 1;
+ if(!b.isWin){
+ win = Math.min(win,b.cnt);
+ }else{
+ lose = Math.max(lose,b.cnt);
+ }
+
+
+ }
+ }
+
+ if (win == max && lose == 0) {
+ return new Result(false, move);
+ } else if (win != max) {
+ return new Result(true, win);
+ } else {
+ return new Result(false, lose);
+ }
+ }
+}
\ No newline at end of file
diff --git "a/\352\271\200\354\261\204\354\233\220/week18/BJ_14630.java" "b/\352\271\200\354\261\204\354\233\220/week18/BJ_14630.java"
new file mode 100644
index 0000000..54c248d
--- /dev/null
+++ "b/\352\271\200\354\261\204\354\233\220/week18/BJ_14630.java"
@@ -0,0 +1,86 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.*;
+
+class Edge implements Comparable {
+ public int vex;
+ public int cost;
+
+ Edge(int vex, int cost) {
+ this.vex = vex;
+ this.cost = cost;
+ }
+
+ @Override
+ public int compareTo(Edge ob) {
+ return this.cost - ob.cost;
+ }
+}
+
+public class BJ_14630 {
+
+ static int N;
+ static int arr[][];
+ static String[] s;
+ static int len;
+ static int[] dis;
+ static int start;
+ static int end;
+
+ public void dijkstra() {
+ PriorityQueue pQ = new PriorityQueue<>();
+ pQ.offer(new Edge(start, 0));
+ dis[start] = 0;
+
+ while (!pQ.isEmpty()) {
+ Edge tmp = pQ.poll();
+ int now = tmp.vex;
+ int nowCost = tmp.cost;
+ if (nowCost > dis[now]) continue;
+ for (int i = 0; i < N; i++) {
+ int next = i;
+ int nextCost = arr[now][i];
+ if (dis[next] > nowCost + nextCost) {
+ dis[next] = nowCost + nextCost;
+ pQ.offer(new Edge(next, nowCost + nextCost));
+ }
+ }
+ }
+ }
+
+
+ public static void main(String[] args) throws IOException {
+ Main T = new Main();
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ N = Integer.parseInt(br.readLine());
+ arr = new int[N][N];
+ s = new String[N];
+
+ for (int i = 0; i < N; i++) {
+ s[i] = br.readLine();
+ }
+
+ StringTokenizer st = new StringTokenizer(br.readLine());
+ start = Integer.parseInt(st.nextToken()) - 1;
+ end = Integer.parseInt(st.nextToken()) - 1;
+
+ len = s[0].length();
+ dis = new int[N];
+ Arrays.fill(dis, Integer.MAX_VALUE);
+
+ for (int i = 0; i < N; i++) {
+ for (int j = 0; j < N; j++) {
+ int sum = 0;
+ for (int k = 0; k < len; k++) {
+ sum += (s[i].charAt(k) - s[j].charAt(k)) * (s[i].charAt(k) - s[j].charAt(k));
+ }
+ arr[i][j] = sum;
+ arr[j][i] = sum;
+ }
+ }
+
+ T.dijkstra();
+ System.out.println(dis[end]);
+ }
+}
\ No newline at end of file
diff --git "a/\352\271\200\354\261\204\354\233\220/week19/BJ_1780.java" "b/\352\271\200\354\261\204\354\233\220/week19/BJ_1780.java"
new file mode 100644
index 0000000..b70a21d
--- /dev/null
+++ "b/\352\271\200\354\261\204\354\233\220/week19/BJ_1780.java"
@@ -0,0 +1,66 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.*;
+
+public class Main {
+ static int N;
+ static int[][] arr;
+ static int a, b, c; // -1,0,1
+
+ static void partition(int row, int cal, int size) {
+ if (isSameColor(row,cal,size)) {
+ if(arr[row][cal] == -1) a++;
+ else if(arr[row][cal] == 0) b++;
+ else c++;
+
+ return;
+ }
+
+ int newSize = size / 3 ;
+
+ partition(row,cal,newSize);
+ partition(row,cal+newSize,newSize);
+ partition(row,cal+2*newSize, newSize);
+
+ partition(row+newSize,cal,newSize);
+ partition(row+newSize,cal+newSize,newSize);
+ partition(row+newSize,cal+2*newSize, newSize);
+
+ partition(row+2*newSize,cal,newSize);
+ partition(row+2*newSize,cal+newSize,newSize);
+ partition(row+2*newSize,cal+2*newSize, newSize);
+ }
+
+ private static boolean isSameColor(int row,int cal, int size) {
+ int color = arr[row][cal];
+ for (int i = row; i < row + size; i++) {
+ for (int j = cal; j < cal + size; j++) {
+ if(color != arr[i][j]) return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static void main(String[] args) throws IOException {
+ Main T = new Main();
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ N = Integer.parseInt(br.readLine());
+ a = b = c = 0;
+ arr = new int[N][N];
+ for (int i = 0; i < N; i++) {
+ StringTokenizer st = new StringTokenizer(br.readLine());
+ for (int j = 0; j < N; j++) {
+ arr[i][j] = Integer.parseInt(st.nextToken());
+ }
+ }
+
+
+ partition(0,0,N);
+ System.out.println(a);
+ System.out.println(b);
+ System.out.println(c);
+
+ }
+}
\ No newline at end of file
diff --git "a/\352\271\200\354\261\204\354\233\220/week19/BJ_22352.java" "b/\352\271\200\354\261\204\354\233\220/week19/BJ_22352.java"
new file mode 100644
index 0000000..f0818af
--- /dev/null
+++ "b/\352\271\200\354\261\204\354\233\220/week19/BJ_22352.java"
@@ -0,0 +1,96 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.*;
+
+class Point {
+ int x;
+ int y;
+
+ public Point(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+}
+
+public class Main {
+
+ static int N,M;
+ static int[][] start;
+ static int[][] end;
+ static boolean[][] ch;
+ static int[] dx = {-1, 1, 0, 0};
+ static int[] dy = {0, 0, -1, 1};
+ static int startVal,endValue,cnt;
+ static boolean isAnswer;
+
+ static void bfs(int x, int y) {
+ Queue Q = new LinkedList<>();
+ Q.add(new Point(x, y));
+ ch[x][y] = true;
+
+ while (!Q.isEmpty()) {
+ Point now = Q.poll();
+ for (int i = 0; i < 4; i++) {
+ int nx = now.x + dx[i];
+ int ny = now.y + dy[i];
+ if(nx < 0 || ny < 0 || nx >= N || ny >= M) continue;
+ if(ch[nx][ny]) continue;
+ if(startVal != start[nx][ny]) continue;
+ if(endValue != end[nx][ny]) isAnswer = false;
+ ch[nx][ny] = true;
+ Q.add(new Point(nx, ny));
+ }
+ }
+ }
+
+ public String solution() {
+ cnt = 0;
+ for (int i = 0; i < N; i++) {
+ for (int j = 0; j < M; j++) {
+ if (!ch[i][j]) {
+ startVal = start[i][j];
+ endValue = end[i][j];
+ if(startVal != endValue) cnt++;
+ bfs(i,j);
+ }
+ }
+ }
+
+ if(!isAnswer) return "NO";
+ if(cnt <= 1) return "YES";
+ else return "NO";
+ }
+
+ public static void main(String[] args) throws IOException {
+ Main T = new Main();
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ StringTokenizer st = new StringTokenizer(br.readLine());
+
+ N = Integer.parseInt(st.nextToken());
+ M = Integer.parseInt(st.nextToken());
+ start = new int[N][M];
+ end = new int[N][M];
+ ch = new boolean[N][M];
+ isAnswer = true;
+
+ for (int i = 0; i < N; i++) {
+ st = new StringTokenizer(br.readLine());
+ for (int j = 0; j < M; j++) {
+ start[i][j] = Integer.parseInt(st.nextToken());
+ }
+ }
+
+
+ for (int i = 0; i < N; i++) {
+ st = new StringTokenizer(br.readLine());
+ for (int j = 0; j < M; j++) {
+ end[i][j] = Integer.parseInt(st.nextToken());
+ }
+ }
+
+
+ System.out.println(T.solution());
+
+ }
+}
\ No newline at end of file
diff --git "a/\352\271\200\354\261\204\354\233\220/week20/BJ_1780.java" "b/\352\271\200\354\261\204\354\233\220/week20/BJ_1780.java"
new file mode 100644
index 0000000..b70a21d
--- /dev/null
+++ "b/\352\271\200\354\261\204\354\233\220/week20/BJ_1780.java"
@@ -0,0 +1,66 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.*;
+
+public class Main {
+ static int N;
+ static int[][] arr;
+ static int a, b, c; // -1,0,1
+
+ static void partition(int row, int cal, int size) {
+ if (isSameColor(row,cal,size)) {
+ if(arr[row][cal] == -1) a++;
+ else if(arr[row][cal] == 0) b++;
+ else c++;
+
+ return;
+ }
+
+ int newSize = size / 3 ;
+
+ partition(row,cal,newSize);
+ partition(row,cal+newSize,newSize);
+ partition(row,cal+2*newSize, newSize);
+
+ partition(row+newSize,cal,newSize);
+ partition(row+newSize,cal+newSize,newSize);
+ partition(row+newSize,cal+2*newSize, newSize);
+
+ partition(row+2*newSize,cal,newSize);
+ partition(row+2*newSize,cal+newSize,newSize);
+ partition(row+2*newSize,cal+2*newSize, newSize);
+ }
+
+ private static boolean isSameColor(int row,int cal, int size) {
+ int color = arr[row][cal];
+ for (int i = row; i < row + size; i++) {
+ for (int j = cal; j < cal + size; j++) {
+ if(color != arr[i][j]) return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static void main(String[] args) throws IOException {
+ Main T = new Main();
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ N = Integer.parseInt(br.readLine());
+ a = b = c = 0;
+ arr = new int[N][N];
+ for (int i = 0; i < N; i++) {
+ StringTokenizer st = new StringTokenizer(br.readLine());
+ for (int j = 0; j < N; j++) {
+ arr[i][j] = Integer.parseInt(st.nextToken());
+ }
+ }
+
+
+ partition(0,0,N);
+ System.out.println(a);
+ System.out.println(b);
+ System.out.println(c);
+
+ }
+}
\ No newline at end of file
diff --git "a/\354\240\204\354\260\254\354\235\230/20220425/BOJ_1949.cpp" "b/\354\240\204\354\260\254\354\235\230/20220425/BOJ_1949.cpp"
index 843a36b..c2af2f0 100644
--- "a/\354\240\204\354\260\254\354\235\230/20220425/BOJ_1949.cpp"
+++ "b/\354\240\204\354\260\254\354\235\230/20220425/BOJ_1949.cpp"
@@ -3,12 +3,10 @@ using namespace std;
int N,M;
int m[10001]{};
-int dp[10001][2]{}; // 0:우수x , 1:우수o
+int dp[10001][2]{};
vector adj[10001]{};
-int par[10001]{};
void makeTree(int now, int parent){
- par[now] = parent;
for(int i=0; i
+using namespace std;
+using tpi = tuple;
+const int INF = 0x3f3f3f3f;
+
+vector adj[1001]{};
+int trapChk[1001]{};
+int dp[1001][1<<10];
+
+void dijk(int st){
+ memset(dp,0x3f,sizeof(dp));
+ priority_queue, greater> pq;
+ pq.push({0,st,0}); // dist, node, mask
+ dp[st][0] = 0;
+
+ while(!pq.empty()){
+ int cd, cn, cm, ct;
+ tie(cd, cn, cm) = pq.top();
+ pq.pop();
+ if(trapChk[cn]) ct = (cm&(1<<(trapChk[cn]-1)))>0 ? 1 : 0;
+ else ct = -1;
+
+ if(cd > dp[cn][cm]) continue;
+ for(int i=0; i0 ? 1 : 0;
+ else nt = -1;
+ int nm = cm;
+
+ if(ct==-1 && nt==-1) ;
+ else if(ct!=-1 && nt==-1) { // cur만 trap
+ if(ct!=t) continue;
+ } else if(ct==-1 && nt!=-1) { // next만 trap
+ if(nt!=t) continue;
+ nm = nm^(1<<(trapChk[nn]-1));
+ } else { // cur, next 둘다 trap
+ if(!(ct^nt) && t) continue;
+ if((ct^nt) && !t) continue;
+ nm = nm^(1<<(trapChk[nn]-1));
+ }
+
+ nd += cd;
+ if(nd < dp[nn][nm]){
+ pq.push({nd,nn,nm});
+ dp[nn][nm] = nd;
+ }
+ }
+ }
+}
+
+int solution(int n, int start, int end, vector> roads, vector traps) {
+ int bitIdx = 1;
+ for(int i=0; i
+using namespace std;
+
+int getSize(int k){
+ if(k==0) return 4;
+ if(k==1) return 3;
+ if(k==2) return 3;
+ if(k==3) return 5;
+ if(k==4) return 4;
+ if(k==5) return 4;
+ if(k==6) return 3;
+ if(k==7) return 5;
+ if(k==8) return 5;
+ if(k==9) return 4;
+}
+
+int getNum(char ch1, char ch2){
+ if(ch1=='z') return 0;
+ if(ch1=='o') return 1;
+ if(ch1=='t') {
+ if(ch2=='w') return 2;
+ else return 3;
+ }
+ if(ch1=='f') {
+ if(ch2=='o') return 4;
+ else return 5;
+ }
+ if(ch1=='s') {
+ if(ch2=='i') return 6;
+ else return 7;
+ }
+ if(ch1=='e') return 8;
+ return 9;
+}
+
+int solution(string s) {
+ int ans = 0;
+ for(int i=0; i='0' && ch<='9') {
+ ans *= 10;
+ ans += (ch-'0');
+ continue;
+ }
+ int tmp = getNum(ch, s[i+1]);
+ ans *= 10;
+ ans += tmp;
+ i+= (getSize(tmp)-1);
+ }
+ return ans;
+}
\ No newline at end of file
diff --git "a/\354\240\204\354\260\254\354\235\230/20220428/prgrms_\354\213\234\355\227\230\354\236\245\353\202\230\353\210\204\352\270\260.cpp" "b/\354\240\204\354\260\254\354\235\230/20220428/prgrms_\354\213\234\355\227\230\354\236\245\353\202\230\353\210\204\352\270\260.cpp"
new file mode 100644
index 0000000..1ae5025
--- /dev/null
+++ "b/\354\240\204\354\260\254\354\235\230/20220428/prgrms_\354\213\234\355\227\230\354\236\245\353\202\230\353\210\204\352\270\260.cpp"
@@ -0,0 +1,68 @@
+#include
+#define xx first
+#define yy second
+using namespace std;
+using pii = pair;
+
+int N,M,root, maxValue=0;
+vector nums;
+vector adj[10001]{};
+
+int K = 1;
+int isP(int now, int mid) {
+ int cur = nums[now];
+ if(adj[now].size()==0) return cur;
+
+ int k=1, a,b;
+ a = adj[now][0];
+ int asum = isP(a, mid);
+ if(adj[now].size()==1) {
+ if(cur+asum <= mid) return cur+asum;
+ else {K++; return cur;}
+ }
+ b = adj[now][1];
+ int bsum = isP(b, mid);
+
+ if(cur+asum+bsum <= mid) return cur+asum+bsum;
+ else {
+ K++;
+ if(cur+asum > mid && cur+bsum > mid) { K++; return cur; }
+ if(cur+asum <= mid && cur+bsum <= mid) return cur + min(asum, bsum);
+ if(cur+asum <= mid) return cur+asum;
+ if(cur+bsum <= mid) return cur+bsum;
+ }
+}
+
+int solution(int k, vector num, vector> links) {
+ nums = num;
+ bool vi[10001]{};
+ for(int i=0; i
+#define xx first
+#define yy second
+using namespace std;
+using pii = pair;
+
+int N, st, ed;
+string m[1001]{};
+int dp[1001]{};
+
+void dijk() {
+ memset(dp,0x3f,sizeof(dp));
+ priority_queue pq;
+ pq.push({0,st});
+ dp[st] = 0;
+
+ while(!pq.empty()){
+ int cd = pq.top().xx;
+ int cp = pq.top().yy;
+ string now = m[cp];
+ pq.pop();
+
+ if(cd > dp[cp]) continue;
+
+ for(int i=1; i<=N; i++){
+ if(cp==i) continue;
+ string next = m[i];
+ int sum = 0;
+ for(int k=0; k>N;
+ string str;
+ for(int i=1; i<=N; i++){
+ cin>>m[i];
+ }
+ cin>>st>>ed;
+ dijk();
+ cout<
+#define xx first
+#define yy second
+using namespace std;
+using tpi = tuple;
+
+int N, M;
+int par[1001]{};
+vector edges;
+
+int find(int k) {
+ if (k == par[k]) return k;
+ else return par[k] = find(par[k]);
+}
+
+void merge(int a, int b) {
+ a = find(a);
+ b = find(b);
+ par[a] = b;
+}
+
+int main(){
+ ios_base::sync_with_stdio(0);
+ cin.tie(0);
+
+ cin>>N;
+ cin>>M;
+ int a,b,c;
+ for(int i=0; i<=N; i++) par[i] = i;
+ for(int i=0; i>a>>b>>c;
+ edges.push_back({c,a,b});
+ }
+ sort(edges.begin(), edges.end());
+
+ int sum = 0;
+ for(int i=0; i
+using namespace std;
+using ll = long long;
+
+ll N;
+ll m[10001]{};
+
+int main() {
+ ios_base::sync_with_stdio(0);
+ cin.tie(0);
+ cin>>N;
+ for(ll i=0; i>m[i];
+ }
+ sort(m,m+N);
+
+ ll ans = 0;
+ for(ll i=0; i0) break;
+ ll st = i+1;
+ ll ed = N-1;
+ ll num = m[i]*-1;
+ while(st num) {
+ ll ted = ed;
+ while(m[ted]==m[ed]) ted--;
+ ed = ted;
+ } else if(m[st]+m[ed] < num) {
+ ll tst = st;
+ while(m[tst]==m[st]) tst++;
+ st = tst;
+ } else {
+ if(m[st]==m[ed]) {
+ ll n = ed-st+1;
+ ans += (n*(n-1))/2;
+ break;
+ }
+ ll tst = st, ted = ed;
+ while(m[ted]==m[ed]) ted--;
+ while(m[tst]==m[st]) tst++;
+ ans += (tst-st)*(ed-ted);
+ st = tst;
+ ed = ted;
+ }
+ }
+ }
+ cout<
+using namespace std;
+using ll = long long;
+
+ll K,N;
+ll m[10001]{};
+
+bool isP(ll mid) {
+ ll cnt = 0;
+ for(ll i=0; i=N) return true;
+ else return false;
+}
+
+int main() {
+ ios_base::sync_with_stdio(0);
+ cin.tie(0);
+ cin>>K>>N;
+ for(ll i=0; i>m[i];
+ }
+
+ ll st = 1, ed = 2147483647;
+ while(st<=ed) {
+ ll mid = (st+ed)>>1;
+ if(isP(mid)) st = mid + 1;
+ else ed = mid - 1;
+ }
+ cout<
+using namespace std;
+const int INF = 0x3f3f3f3f;
+
+int N,M,t;
+int m[11]{};
+vector adj[11]{};
+bool maskVi[1<<10]{};
+bool vi[11]{};
+
+int bfs(int mask) {
+ memset(vi,0,sizeof(vi));
+ queue q;
+ int cnt = 0;
+ int sum = 0;
+ for(int i=0; i>N;
+ for(int i=0; i>m[i];
+ for(int i=0; i>M;
+ for(int j=0; j>t;
+ adj[i].push_back(t-1);
+ }
+ }
+
+ int ans = INF;
+ for(int mask=1; mask<(1<
+#define xx first
+#define yy second
+using namespace std;
+using pii = pair;
+using dpi = pair;
+
+int N,M,ans=0;
+int m[21][21]{};
+bool vi[21][21]{};
+bool vi2[21][21]{};
+int dy[4] = {-1,1,0,0};
+int dx[4] = {0,0,-1,1};
+
+void rotateBlock(){
+ int tmp[21][21]{};
+ memcpy(tmp, m, sizeof(tmp));
+ for(int i=0,jj=N-1; i q;
+ q.push({sty,stx});
+ vi[sty][stx] = true;
+ vi2[sty][stx] = true;
+ int cnt = 1;
+ int rainbow = 0;
+
+ while(!q.empty()){
+ int cy = q.front().xx;
+ int cx = q.front().yy;
+ q.pop();
+
+ for(int i=0; i<4; i++){
+ int ny = cy + dy[i];
+ int nx = cx + dx[i];
+ if(ny<0 || nx<0 || ny>=N || nx>=N || vi[ny][nx]) continue;
+ if(m[ny][nx]==0 || m[ny][nx]==m[sty][stx]) {
+ q.push({ny,nx});
+ vi[ny][nx] = true;
+ if(!m[ny][nx]) rainbow++;
+ else vi2[ny][nx] = true;
+ cnt++;
+ }
+ }
+ }
+ return pii(cnt, rainbow);
+}
+
+void makeGravity(){
+ vector v;
+ for(int j=0; j=0 && m[i][j]<=M) {
+ v.push_back(m[i][j]);
+ m[i][j] = 9;
+ }
+ if(v.size() && (i==N || m[i][j]==-1)) {
+ int ti = i-1, tj = j;
+ for(int k=v.size()-1; k>=0; k--){
+ m[ti--][tj] = v[k];
+ }
+ v.clear();
+ }
+ }
+ }
+}
+
+bool eraseBlock(){
+ vector v;
+ memset(vi2,0,sizeof(vi2));
+ for(int i=0; i0 && m[i][j]<=M) {
+ pii tmp = bfs(i,j);
+ if(tmp.xx < 2) continue;
+ v.push_back({tmp, {i,j}});
+ }
+ }
+ }
+ if(v.size()==0) return false;
+ sort(v.begin(), v.end(), greater());
+ int score = bfs(v[0].yy.xx, v[0].yy.yy).xx;
+ ans += (score*score);
+ for(int i=0; i>N>>M;
+ for(int i=0; i>m[i][j];
+ }
+ }
+
+ while(eraseBlock()){
+ makeGravity();
+ rotateBlock();
+ makeGravity();
+ }
+ cout<
+#define xx first
+#define yy second
+using namespace std;
+using pii = pair;
+using ll = long long;
+
+const int MAX = 9999;
+int sieve[MAX+1];
+void find_prime(){
+ memset(sieve, -1, sizeof(sieve));
+ for(ll i=2; i*i<=MAX; ++i)
+ if(sieve[i] == -1)
+ for(ll j=i*i; j<=MAX; j+=i)
+ if(sieve[j] == -1)
+ sieve[j] = i;
+}
+
+int N;
+int vi[10000]{};
+
+int bfs(int a, int b){
+ memset(vi,0,sizeof(vi));
+ queue q;
+ q.push({a,0});
+ vi[a] = true;
+
+ while(!q.empty()){
+ int now = q.front().xx;
+ int dist = q.front().yy;
+ q.pop();
+
+ if(now==b) return dist;
+
+ for(int i=1; i<=1000; i*=10){
+ for(int k=0; k<10; k++){
+ if(i==1000 && k==0) continue;
+ int tmp = now/(i*10);
+ int next = k*i + tmp*(i*10) + now%i;
+ if(sieve[next]<0 && !vi[next]) {
+ q.push({next,dist+1});
+ vi[next] = true;
+ }
+ }
+ }
+ }
+
+ return -1;
+}
+
+int main() {
+ ios_base::sync_with_stdio(0);
+ cin.tie(0);
+ find_prime();
+ cin>>N;
+ int a,b;
+
+ while(N--){
+ cin>>a>>b;
+ int ret = bfs(a,b);
+ if(ret<0) cout<<"Impossible"<<'\n';
+ else cout<
+#define xx first
+#define yy second
+using namespace std;
+using pii = pair;
+
+int N,M;
+int m[31][31]{};
+int m2[31][31]{};
+bool vi[31][31]{};
+int dy[4] = {-1,1,0,0};
+int dx[4] = {0,0,-1,1};
+
+void bfs(int sty, int stx){
+ queue q;
+ q.push({sty,stx});
+ vi[sty][stx] = true;
+
+ while(!q.empty()) {
+ int cy = q.front().xx;
+ int cx = q.front().yy;
+ q.pop();
+
+ for(int i=0; i<4; i++){
+ int ny = cy + dy[i];
+ int nx = cx + dx[i];
+ if(ny<0 || nx<0 || ny>=N || nx>=M || vi[ny][nx] || m[ny][nx]!=m[sty][stx]) continue;
+ q.push({ny,nx});
+ vi[ny][nx] = true;
+ }
+ }
+}
+
+int main() {
+ ios_base::sync_with_stdio(0);
+ cin.tie(0);
+ cin>>N>>M;
+ for(int i=0; i>m[i][j];
+ }
+ }
+
+ for(int i=0; i>m2[i][j];
+ }
+ }
+
+ bool chk = false;
+ bool ret = true;
+ int vac = 0;
+ for(int i=0; i
+#define xx first
+#define yy second
+using namespace std;
+using pii = pair;
+
+int N,M;
+int m[301][301]{};
+int m2[301][301]{};
+bool vi[301][301]{};
+int dy[4] = {-1,1,0,0};
+int dx[4] = {0,0,-1,1};
+
+void melt(){
+ memcpy(m2,m,sizeof(m2));
+ for(int i=0; i=N || nx>=M) continue;
+ if(m[ny][nx] && m2[ny][nx]) m2[ny][nx]--;
+ }
+ }
+ }
+ memcpy(m,m2,sizeof(m));
+}
+
+int bfs(){
+ int sty=-1, stx=-1;
+ for(int i=0; i=0) break;
+ }
+ if(sty<0) return 0;
+
+ memset(vi,0,sizeof(vi));
+ queue q;
+ q.push({sty,stx});
+ vi[sty][stx] = true;
+
+ while(!q.empty()) {
+ int cy = q.front().xx;
+ int cx = q.front().yy;
+ q.pop();
+
+ for(int i=0; i<4; i++){
+ int ny = cy + dy[i];
+ int nx = cx + dx[i];
+ if(ny<0 || nx<0 || ny>=N || nx>=M || vi[ny][nx] || !m[ny][nx]) continue;
+ q.push({ny,nx});
+ vi[ny][nx] = true;
+ }
+ }
+
+ for(int i=0; i>N>>M;
+ for(int i=0; i>m[i][j];
+ }
+ }
+
+ int ans = 0;
+ while(true){
+ int ret = bfs();
+ if(ret==0) {
+ cout<<0;
+ break;
+ } else if(ret==1) {
+ melt();
+ } else { // ret==2
+ cout<
+#define xx first
+#define yy second
+using namespace std;
+using ll = long long;
+using pll = pair;
+using tpl = tuple;
+const ll INF = 0x3f3f3f3f3f3f3f3f * 2;
+
+ll N,M,K;
+vector adj[10001]{};
+ll dp[10001][21]{};
+
+void dijk(){
+ priority_queue, greater> pq;
+ pq.push({0,1,0}); // dist, node, count
+ dp[1][0] = 0;
+
+ while(!pq.empty()){
+ ll cd, cn, ccnt;
+ tie(cd, cn, ccnt) = pq.top();
+ pq.pop();
+
+ if(cd > dp[cn][ccnt]) continue;
+ for(auto val : adj[cn]){
+ ll nd = cd + val.yy;
+ ll nn = val.xx;
+ if(nd < dp[nn][ccnt]) {
+ dp[nn][ccnt] = nd;
+ pq.push({nd, nn, ccnt});
+ }
+ if(ccnt+1 > K) continue;
+ if(cd < dp[nn][ccnt+1]){
+ dp[nn][ccnt+1] = cd;
+ pq.push({cd, nn, ccnt+1});
+ }
+ }
+ }
+}
+
+int main() {
+ ios_base::sync_with_stdio(0);
+ cin.tie(0);
+ memset(dp,0x3f,sizeof(dp));
+ cin>>N>>M>>K;
+ ll a,b,c;
+ for(ll i=0; i>a>>b>>c;
+ adj[a].push_back({b,c});
+ adj[b].push_back({a,c});
+ }
+
+ dijk();
+
+ ll ans = INF;
+ for(ll i=0; i<=K; i++){
+ ans = min(ans, dp[N][i]);
+ }
+ cout<
+using namespace std;
+
+struct FB{
+ int R,C,M,S,D,SZ;
+ FB(int R_=0, int C_=0, int M_=0, int S_=0, int D_=-1, int SZ_=0)
+ : R(R_), C(C_), M(M_), S(S_), D(D_), SZ(SZ_){}
+};
+
+int N,M,K;
+FB m[50][50]{};
+vector fb;
+int dy[8] = {-1,-1,0,1,1,1,0,-1};
+int dx[8] = {0,1,1,1,0,-1,-1,-1};
+int dd[2][4] = {{0, 2, 4, 6}, {1, 3, 5, 7}};
+
+void divideFb(){
+ fb.clear();
+ for(int i=0; i>N>>M>>K;
+ int a,b,c,d,e;
+ for(int i=0; i>a>>b>>c>>d>>e;
+ fb.push_back(FB(a-1, b-1, c, d, e, 1));
+ }
+
+ while(K--){
+ fbMove();
+ divideFb();
+ }
+
+ int ans = 0;
+ for(auto val : fb){
+ ans += val.M;
+ }
+ cout<
+using namespace std;
+using ll = long long;
+
+ll N;
+ll m[105]{};
+ll dp[105][21]{};
+
+int main() {
+ ios_base::sync_with_stdio(0);
+ cin.tie(0);
+ cin>>N;
+ for(ll i=0; i>m[i];
+ }
+
+ dp[0][m[0]] = 1;
+ for(ll i=1; i<(N-1); i++){
+ ll now = m[i];
+ for(ll j=0; j<=20; j++){
+ if(j-now >= 0) dp[i][j] += dp[i-1][j-now];
+ if(j+now <= 20) dp[i][j] += dp[i-1][j+now];
+ }
+ }
+ cout<
+#include
+using namespace std;
+
+int N;
+int v[2001]{};
+int main() {
+ ios_base::sync_with_stdio(0);
+ cin.tie(0);
+ cin>>N;
+ for(int i=0; i>v[i];
+ sort(v,v+N);
+
+ int cnt=0;
+ for(int i=0; i v[i]) r--;
+ else {
+ if(i!=l && i!=r) {cnt++; break;}
+ if(i==l) l++;
+ else if(i==r) r--;
+ }
+ }
+ }
+ cout<
+using namespace std;
+
+int N,M;
+int m[501][501]{};
+int dp[501][501]{};
+int dy[4] = {-1,0,1,0};
+int dx[4] = {0,1,0,-1};
+
+int solve(int y, int x){
+ if(y<0 || x<0 || y>=N || x>=M) return 1;
+ if(dp[y][x]!=-1) return dp[y][x];
+ int &ret = dp[y][x];
+ ret = 0;
+ int ny = y + dy[m[y][x]];
+ int nx = x + dx[m[y][x]];
+ ret = solve(ny, nx);
+ return ret;
+}
+
+int main() {
+ ios_base::sync_with_stdio(0);
+ cin.tie(0);
+ memset(dp,-1,sizeof(dp));
+ cin>>N>>M;
+ string str;
+ for(int i=0; i>str;
+ for(int j=0; j
+using namespace std;
+
+int N;
+int m[2200][2200]{};
+int ans_[3]{}, *ans = ans_ + 1;
+
+void func(int y, int x, int k){
+ int chk = m[y][x];
+ bool flag = false;
+ for(int i=y; i>N;
+ for(int i=0; i>m[i][j];
+ }
+ }
+
+ func(0,0,N);
+ for(int i=0; i<3; i++) cout<
+using namespace std;
+const int MOD = 1e5;
+
+int N,M;
+int dp[102][102][4]{};
+int dy[2] = {1,0};
+int dx[2] = {0,1};
+
+int main() {
+ ios_base::sync_with_stdio(0);
+ cin.tie(0);
+ cin>>N>>M;
+
+ dp[2][0][0] = 1;
+ dp[1][1][1] = 1;
+ dp[1][1][2] = 1;
+ dp[0][2][3] = 1;
+
+ for(int i=0; i
+using namespace std;
+const int INF = 0x3f3f3f3f;
+
+int N,M,K, ans=INF;
+int chkMask[16][9]{};
+vector stk;
+
+void dfs2(int dpt, int mask, int now){
+ if(dpt==M || dpt==K || dpt+1 >= ans) return;
+
+ for(int i=now+1; i weak, vector dist) {
+ N = n; // 외벽길이
+ M = weak.size(); // 취약점 개수
+ K = dist.size(); // 친구들의 수
+
+ for(int i=0; i=N-1) {
+ chkMask[i][j] = (1<=0; k--) {
+ // cout<<(chkMask[i][j]>>k & 1);
+ // }
+ // cout<<'\n';
+ // }
+ // }
+
+ if(ans==INF) return -1;
+ else return ans;
+}
\ No newline at end of file
diff --git "a/\354\240\204\354\260\254\354\235\230/resources/level-5.png" "b/\354\240\204\354\260\254\354\235\230/resources/level-5.png"
new file mode 100644
index 0000000..b395121
Binary files /dev/null and "b/\354\240\204\354\260\254\354\235\230/resources/level-5.png" differ