From eeeeafffe76404c7d34337dbf2c5f74c5481992c Mon Sep 17 00:00:00 2001 From: "YeJun, Jung" Date: Sun, 15 Feb 2026 07:39:40 +0900 Subject: [PATCH 01/12] feat: add boj p1074 solution --- problems/baekjoon/p1074/Main.java | 92 +++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 problems/baekjoon/p1074/Main.java diff --git a/problems/baekjoon/p1074/Main.java b/problems/baekjoon/p1074/Main.java new file mode 100644 index 0000000..933a988 --- /dev/null +++ b/problems/baekjoon/p1074/Main.java @@ -0,0 +1,92 @@ +/* + * (1074) Z + * https://www.acmicpc.net/problem/1074 + */ + +import java.io.*; +import java.util.*; + +/** + * Baekjoon - Z + * @author YeJun, Jung + * + * [전략] + * - 주어진 행렬의 크기를 1/4로 줄이면서 탐색한다. + * - 목표 좌표가 현재 부분행렬에서 몇 사분면에 있는지 파악한다. + * - 해당 사분면을 부분행렬로 하여 다음 탐색을 진행한다. + * + * [TIP] + * - 2를 곱하거나 나눌때 비트 연산자를 사용하면 실행속도가 조금 빨라진다. + * - 5 * 2 == 5 << 1 + * - 5 * 2 * 2 == 5 << 2 + * - 5² == 5 << 2 + * - 5 / 2 == 5 >> 1 + * - 5 / 2 / 2 == 5 >> 2 + */ +public class Main { + static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + static BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); + static StringTokenizer input; + + // ---------------------------------------------------------- + + public static void main(String[] args) throws IOException { + new Main().run(); + } + + // ---------------------------------------------------------- + + int boardSize; + int goalX; + int goalY; + int answer; + + public void run() throws IOException { + input(); + solve(); + print(); + } + + private void input() throws IOException { + getLine(); + + boardSize = Integer.parseInt(input.nextToken()); + goalY = Integer.parseInt(input.nextToken()); + goalX = Integer.parseInt(input.nextToken()); + } + + private void solve() { + answer = search(1 << boardSize, goalX, goalY); // 1 << N == 2ⁿ (단, N ≧ 1) + } + + private int search(int size, int x, int y) { + int nSize = size >> 1; // N >> 1 == N / 2 + int horizontal = x < nSize ? 0 : 1; // 왼쪽(0), 오른쪽(1) + int vertical = y < nSize ? 0 : 1; // 위(0), 아래(1) + int quad = horizontal + (2 * vertical); // 0, 1, 2, 3 사분면 + + // 크가가 2이하가 되면 quad(사분면)을 반환하고 탐색을 종료한다. + if (size <= 2) return quad; + + // 다음 탐색할 부분행렬 이전까지의 타일의 개수 + int tileNm = (nSize * nSize) * quad; + + // 다음 위치 + int nx = x - (nSize * horizontal); + int ny = y - (nSize * vertical); + + // 재귀 호출 + return tileNm + search(nSize, nx, ny); + } + + private void print() throws IOException { + writer.write(answer + "\n"); + writer.flush(); + } + + // ---------------------------------------------------------- + + private void getLine() throws IOException { + input = new StringTokenizer(reader.readLine().trim()); + } +} From a5f029468049736c3bd728522d14c87eb7c9371d Mon Sep 17 00:00:00 2001 From: "YeJun, Jung" Date: Sun, 15 Feb 2026 10:53:50 +0900 Subject: [PATCH 02/12] feat: add boj p3109 solution --- problems/baekjoon/p3109/Main.java | 141 ++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 problems/baekjoon/p3109/Main.java diff --git a/problems/baekjoon/p3109/Main.java b/problems/baekjoon/p3109/Main.java new file mode 100644 index 0000000..963480e --- /dev/null +++ b/problems/baekjoon/p3109/Main.java @@ -0,0 +1,141 @@ +/* + * (3109) 빵집 + * https://www.acmicpc.net/problem/3109 + */ + +import java.io.*; +import java.util.*; + +/** + * Baekjoon - 빵집 + * @author YeJun, Jung + * + * [전략] + * - DFS with DP + Greedy + * - 각 출발지점(열이 0인 모든 행)에 대해서 파이프 설치를 시도한다. + * - addPipe(int startY) + * - 마지막 열에 도착할때까지 DFS 하면서... + * - DP: 막힌 구간(대각선 및 오른쪽으로 이동 불가능) 혹은 이미 방문한 장소에 대해서 + * 기록하여 반복해서 해당 구역을 탐색하는 것을 방지한다. + * - Greedy: 대각선 위, 오른쪽, 대각선 아래 순서로 탐색하면서, 마지막 열에 + * 도착하면 탐색을 중단한다. + * + * [시간복잡도 분석] + * - DFS에 대해서 각 열에 대해서 3방향으로 이동 가능하기 때문에 30,000 만큼 시간이 걸린다. + * - 출발 지점이 높이 만큼 있으므로 500 * 30,000 = 15,000,000 만큼의 시간이 걸린다. + * - 즉, 최악의 경우 15,000,000만큼 반복문을 도는데, 1억번 반복에 1초 걸린다고 가정했을 때 + * DP, Greedy로 인한 최적화도 있으므로 충분히 시간 제한안에 들어갈 것으로 예상된다. + * - O(R * C * 3) + */ +public class Main { + static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + static BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); + static StringTokenizer input; + + // ---------------------------------------------------------- + + public static void main(String[] args) throws IOException { + new Main().run(); + } + + // ---------------------------------------------------------- + + static final int[] DIR_X = { 1, 1, 1 }; + static final int[] DIR_Y = { 1, 0, -1 }; + static final int DIR_LEN = 3; + + static final int MAX_BOARD_WIDTH = 10000; + static final int MAX_BOARD_HEIGHT = 500; + static final int MAX_STACK_SIZE = MAX_BOARD_WIDTH * DIR_LEN + 100; // 100 is padding + + static int[] pipeX = new int[MAX_STACK_SIZE]; + static int[][] pipeY = new int[MAX_STACK_SIZE][MAX_BOARD_HEIGHT]; + + int answer; + int boardWidth; + int boardHeight; + char[][] board; + + public void run() throws IOException { + input(); + solve(); + print(); + } + + private void input() throws IOException { + getLine(); + boardHeight = Integer.parseInt(input.nextToken()); + boardWidth = Integer.parseInt(input.nextToken()); + + board = new char[boardHeight][]; + + for (int y = 0; y < boardHeight; y++) { + board[y] = reader.readLine().trim().toCharArray(); + } + } + + private void solve() { + answer = 0; + + for (int y = 0; y < boardHeight; y++) { + if (addPipe(y)) ++answer; + } + } + + private boolean addPipe(int startY) { + pipeX[0] = 0; + pipeY[0][0] = startY; + board[startY][0] = 'O'; + + int stackSize = 1, peek = 0; + int n = 0, nx = 0, ny = 0; + int x = 0, y = 0; + boolean hasChild = false; + + while (stackSize > 0) { + peek = --stackSize; + x = pipeX[peek]; + y = pipeY[peek][x]; + hasChild = false; + + if (x == boardWidth - 1) return true; + + // 대각선 아래, 오른쪽, 대각선 위 순으로 stack에 쌓여야만 + // 쌓은 반대인 대각선 위, 오른족, 대각선 아래 순서로 방문할 수 있다. (Greedy) + for (int dir = 0; dir < DIR_LEN; dir++) { + nx = x + DIR_X[dir]; + ny = y + DIR_Y[dir]; + + if (!isInsideBoard(nx, ny) || board[ny][nx] != '.') { + continue; + } + + n = stackSize++; + pipeX[n] = nx; + pipeY[n][nx] = ny; + board[y][x] = 'O'; + + hasChild = true; + } + + if (!hasChild) board[y][x] = 'N'; + } + + return false; + } + + private boolean isInsideBoard(int x, int y) { + return x >= 0 && x < boardWidth && y >= 0 && y < boardHeight; + } + + private void print() throws IOException { + writer.write(answer + "\n"); + writer.flush(); + } + + // ---------------------------------------------------------- + + private static void getLine() throws IOException { + input = new StringTokenizer(reader.readLine().trim()); + } +} From aee9b286f8f5670399c1c3a291f789c960dad9f3 Mon Sep 17 00:00:00 2001 From: "YeJun, Jung" Date: Sun, 15 Feb 2026 15:30:52 +0900 Subject: [PATCH 03/12] feat: add swea p6782 solution --- problems/SWEA/p6782/Solution.java | 95 +++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 problems/SWEA/p6782/Solution.java diff --git a/problems/SWEA/p6782/Solution.java b/problems/SWEA/p6782/Solution.java new file mode 100644 index 0000000..9dcfa5c --- /dev/null +++ b/problems/SWEA/p6782/Solution.java @@ -0,0 +1,95 @@ +/* + * (6782) 현주가 좋아하는 제곱근 놀이 + * https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWgqsAlKr9sDFAW0&categoryId=AWgqsAlKr9sDFAW0&categoryType=CODE&problemTitle=6782&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1 + */ + +import java.io.*; +import java.util.*; + +/** + * SW Expert Academy - 6782. 현주가 좋아하는 제곱근 놀이 + * @author YeJun, Jung + * + * [분석] + * - 주어진 N을 N+1 하면서 sqrt(N) 결과 (정수)가 되도록 만들어야 한다. + * - sqrt(N)은 비용이 낮지만, N+1은 너무 많이 반복해야 한다. + * - 주어지는 숫자가 크기 때문에(10¹²) Long 타입을 사용한다. + * + * [전략] + * - 사전에 2...1,000,000 까지 제곱해서 저장해두고 활용한다.(백만번 반복) + * - sqrt(N) 결과 정수가 아니어서 N+1 해야할 때 사전에 계산해둔 제곱근 결과를 활용한다. + */ +public class Solution { + static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + static BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); + + // ---------------------------------------------------------- + + public static void main(String[] args) throws IOException { + final int testCount = Integer.parseInt(reader.readLine().trim()); + + for (int testCase = 1; testCase <= testCount; testCase++) { + new Solution(testCase).run(); + } + } + + // ---------------------------------------------------------- + + static final int MAX_POW = 1000001; + static long[] powArr = new long[MAX_POW]; + + static { + // 사전에 2...1,000,000 까지 제곱해서 저장해두고 활용한다.(백만번 반복) + for (long num = 2; num < MAX_POW; num++) { + powArr[(int)(num)] = num * num; + } + } + + int testCase; + long startNum; + int answer; + + public Solution(int testCase) { + this.testCase = testCase; + } + + public void run() throws IOException { + input(); + solve(); + print(); + } + + private void input() throws IOException { + startNum = Long.parseLong(reader.readLine().trim()); + } + + private void solve() { + answer = countUntilTwo(startNum); + } + + private int countUntilTwo(long num) { + // 기저 조건 + if (num == 2) return 0; + + // 일단 sqrt(num) 한다. + int sqrt = (int)Math.sqrt(num); + + // sqrt(num) 결과가 정수라면, 바로 sqrt(num) 결과를 적용한다. + if (powArr[sqrt] == num) { + return 1 + countUntilTwo(sqrt); + } + + // sqrt(num) 결과가 정수가 아니라면, 정수가 되도록 num을 조정한다. + sqrt++; + return (int)(powArr[sqrt] - num) + countUntilTwo(powArr[sqrt]); + } + + private void print() throws IOException { + writer.write("#" + testCase); + writer.write(" " + answer); + writer.write("\n"); + writer.flush(); + } + + // ---------------------------------------------------------- +} From 7fa9fa5d79015f87b8bf9c615541a7e8916e2416 Mon Sep 17 00:00:00 2001 From: "YeJun, Jung" Date: Sun, 15 Feb 2026 15:56:14 +0900 Subject: [PATCH 04/12] feat: add swea p4012 solution --- problems/SWEA/p4012/Solution.java | 130 ++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 problems/SWEA/p4012/Solution.java diff --git a/problems/SWEA/p4012/Solution.java b/problems/SWEA/p4012/Solution.java new file mode 100644 index 0000000..a9e885a --- /dev/null +++ b/problems/SWEA/p4012/Solution.java @@ -0,0 +1,130 @@ +/* + * (4012) [모의 SW 역량테스트] 요리사 + * https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWIeUtVakTMDFAVH&categoryId=AWIeUtVakTMDFAVH&categoryType=CODE&problemTitle=4012&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1 + */ + +import java.io.*; +import java.util.*; + +/** + * SW Expert Academy - 4012. [모의 SW 역량테스트] 요리사 + * @author YeJun, Jung + * + * [분석] + * - 주어진 식재료 중에서 N/2를 선택해서 조합한다. + * - 식재료를 조합해서 시너지를 합친다. + * - 두 요리의 시너지 차이의 최솟값을 출력한다. + * + * [전략] + * - 조합을 위해 prevPermutation 메서드를 사용한다. + * - getFoodScore 메서드에서 2중 반복문을 통해 사용한 식재료의 시너지 합을 계산한다. + */ +public class Solution { + static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + static BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); + static StringTokenizer input; + + // ---------------------------------------------------------- + + public static void main(String[] args) throws IOException { + final int testCount = Integer.parseInt(reader.readLine().trim()); + + for (int testCase = 1; testCase <= testCount; testCase++) { + new Solution(testCase).run(); + } + } + + // ---------------------------------------------------------- + + int testCase; + int answer; + int matSize; + int[][] mat; + int[] select; + + public Solution(int testCase) { + this.testCase = testCase; + } + + public void run() throws IOException { + input(); + solve(); + print(); + } + + private void input() throws IOException { + matSize = Integer.parseInt(reader.readLine().trim()); + mat = new int[matSize][matSize]; + + for (int y = 0; y < matSize; y++) { + getLine(); + + for (int x = 0; x < matSize; x++) { + mat[y][x] = Integer.parseInt(input.nextToken()); + } + } + } + + private void solve() { + answer = Integer.MAX_VALUE; + select = new int[matSize]; + + Arrays.fill(select, 0, matSize / 2, 1); + + do { + answer = Math.min(answer, search()); + } while (prevPermutation(select)); + } + + private int search() { + int foodA = getFoodScore(0); + int foodB = getFoodScore(1); + + return Math.abs(foodA - foodB); + } + + private int getFoodScore(int food) { + int result = 0; + + for (int A = 0; A < matSize; A++) { + if (select[A] != food) continue; + for (int B = 0; B < matSize; B++) { + if (select[B] != food) continue; + + result += mat[A][B]; + } + } + + return result; + } + + private void print() throws IOException { + writer.write("#" + testCase); + writer.write(" " + answer); + writer.write("\n"); + writer.flush(); + } + + // ---------------------------------------------------------- + + private static void getLine() throws IOException { + input = new StringTokenizer(reader.readLine().trim()); + } + + private static boolean prevPermutation(int[] x) { + int n = x.length - 1, a = n, b = n; + while (a > 0 && x[a - 1] <= x[a]) a--; + if (a == 0) return false; + while (x[a - 1] <= x[b]) b--; + swap(x, a - 1, b); reverse(x, a, n); + return true; + } + + private static void swap(int[] x, int a, int b) { + int t = x[a]; x[a] = x[b]; x[b] = t; + } + + private static void reverse(int[] x, int a, int b) { + while (a < b) swap(x, a++, b--); + } +} From ac1fe4a5ace88d2c37b5574be459d081cd9a031d Mon Sep 17 00:00:00 2001 From: "YeJun, Jung" Date: Sun, 15 Feb 2026 16:28:55 +0900 Subject: [PATCH 05/12] add swea p1952 solution --- problems/SWEA/p1952/Solution.java | 56 +++++++++++++------------------ 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/problems/SWEA/p1952/Solution.java b/problems/SWEA/p1952/Solution.java index 953b5cc..bcf7880 100644 --- a/problems/SWEA/p1952/Solution.java +++ b/problems/SWEA/p1952/Solution.java @@ -1,11 +1,23 @@ /* - * {풀이 하는 중} (1952) [모의 SW 역량테스트] 수영장 + * (1952) [모의 SW 역량테스트] 수영장 * https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5PpFQaAQMDFAUq&categoryId=AV5PpFQaAQMDFAUq&categoryType=CODE&problemTitle=1952&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1 */ import java.io.*; import java.util.*; +/** + * SW Expert Academy - 1952. [모의 SW 역량테스트] 수영장 + * @author YeJun, Jung + * + * [분석] + * - 각 월에 대해서 1일, 1달, 3달 이용권 중 하나를 선택해서 비용의 최소화 해야 한다. + * + * [전략] + * - DFS(재귀함수)를 사용해서 각 월에 대해서 1일, 1달, 3달 이용권을 시도한다. + * - 만약 계산된 가격이 현재까지의 최적 가격보다 높다면 더 이상 탐색하지 않는다. (backtracking) + * - 각 월에 대한 최적 가격을 기록하여 탐색 횟수를 최적화한다. + */ public class Solution { static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); @@ -38,9 +50,6 @@ public static void main(String[] args) throws IOException { int[] priceArr; int[] planArr; - int[] oneDayTicketArr; - boolean[] monthTicketArr; - public Solution(int testCase) { this.testCase = testCase; } @@ -75,10 +84,6 @@ private void solve() { } bestPrice = priceArr[ONE_YEAR_TICKET]; // 1년 이용권 - - oneDayTicketArr = new int[MONTH_LEN]; - monthTicketArr = new boolean[MONTH_LEN]; - offset = bestPrice * 2; cache = new boolean[13 * offset]; @@ -89,58 +94,43 @@ private void solve() { boolean[] cache; private void searchBestPrice(int month, int currentPrice) { - if (month > MONTH_LEN || currentPrice >= bestPrice) return; + // month가 12월을 넘어가지 않도록 한다. + month = Math.min(month, MONTH_LEN); + // 메모이제이션 int cacheKey = month * offset + currentPrice; - // System.out.printf("searchBestPrice(%d, %d)\n", month, currentPrice); if (cache[cacheKey]) return; cache[cacheKey] = true; - while ( (month < MONTH_LEN) && - (monthTicketArr[month] || oneDayTicketArr[month] >= planArr[month]) - ) { - month++; - } - + // 이용하지 않는 달은 넘어간다. + while ( month < MONTH_LEN && planArr[month] == 0) month++; + // 기저조건 if (month >= MONTH_LEN) { if (currentPrice < bestPrice) bestPrice = currentPrice; - cache[cacheKey] = true; return; } - - // System.out.printf("[%d] searchBestPrice(%d, %d)\n", testCase, month, currentPrice); - - int price; // 1일 이용권 - price = currentPrice + priceArr[ONE_DAY_TICKET]; + int price; + price = currentPrice + priceArr[ONE_DAY_TICKET] * planArr[month]; if (price < bestPrice) { - oneDayTicketArr[month]++; - if (oneDayTicketArr[month] >= planArr[month]) { - searchBestPrice(month + 1, price); - } else { - searchBestPrice(month, price); - } - oneDayTicketArr[month]--; + searchBestPrice(month + 1, price); } // 1달 이용권 price = currentPrice + priceArr[ONE_MONTH_TICKET]; if (price < bestPrice) { - monthTicketArr[month] = true; searchBestPrice(month + 1, price); - monthTicketArr[month] = false; } // 3달 이용권 price = currentPrice + priceArr[THREE_MONTH_TICKET]; if (price < bestPrice) { - for (int m = month; m < month + 2 && m < MONTH_LEN; m++) monthTicketArr[m] = true; searchBestPrice(month + 3, price); - for (int m = month; m < month + 2 && m < MONTH_LEN; m++) monthTicketArr[m] = false; } + // 캐시 cache[cacheKey] = true; } From e7f36a7ecccf45ecb2261ea9ebd63b5b136e7cff Mon Sep 17 00:00:00 2001 From: "YeJun, Jung" Date: Sun, 15 Feb 2026 16:29:27 +0900 Subject: [PATCH 06/12] chore: remove output.txt --- problems/SWEA/p1952/output.txt | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 problems/SWEA/p1952/output.txt diff --git a/problems/SWEA/p1952/output.txt b/problems/SWEA/p1952/output.txt deleted file mode 100644 index 7656bfa..0000000 --- a/problems/SWEA/p1952/output.txt +++ /dev/null @@ -1,9 +0,0 @@ -#1 100 -#2 50 -#3 180 -#4 200 -#5 200 -#6 360 -#7 520 -#8 200 -#9 500 From e23514750ae716f3ff083d7d83bdbe3d1f45faaa Mon Sep 17 00:00:00 2001 From: "YeJun, Jung" Date: Sun, 15 Feb 2026 16:42:50 +0900 Subject: [PATCH 07/12] feat: add boj p6987 solution --- problems/baekjoon/p6987/Main.java | 173 ++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 problems/baekjoon/p6987/Main.java diff --git a/problems/baekjoon/p6987/Main.java b/problems/baekjoon/p6987/Main.java new file mode 100644 index 0000000..c0e16fa --- /dev/null +++ b/problems/baekjoon/p6987/Main.java @@ -0,0 +1,173 @@ +/* + * (6987) 월드컵 + * https://www.acmicpc.net/problem/6987 + */ + +import java.io.*; +import java.util.*; + +/** + * Baekjoon - 월드컵 + * @author YeJun, Jung + * + * [분석] + * - 주어진 경기 결과를 보고, 해당 결과가 존재할 수 있는 경기 결과인지 판단한다. + * + * [전략] + * - 사전 체크 + * - 각 국가의 가로 합은 항상 5가 되어야 함 + * - 모든 숫자를 더했을때 값은 항상 30이 되어야 함 + * - 승이 15면 패가 15여야 함 (승의 합 == 패의 합) + * 누군가 이기면, 누군가 지는것이기 때문 + * - 30 - (승) - (패) == (무)의 합이여 함 + * - DFS + Backtracking + * - 각 팀들과 경기했을 때 결과(승,무,패) 조합에 대해서 DFS한다. + * - 입력된 경기 결과를 벗어난 조합은 탐색할 필요없다. (Backtracking) + */ +public class Main { + static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + static BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); + static StringTokenizer input; + + // ---------------------------------------------------------- + + public static void main(String[] args) throws IOException { + final int testCount = 4; + + for (int testCase = 1; testCase <= testCount; testCase++) { + new Main().run(); + } + + writer.write("\n"); + writer.flush(); + } + + // ---------------------------------------------------------- + + static final int TEAM_LEN = 6; + static final int WIN = 0; + static final int DRAW = 1; + static final int LOSE = 2; + + static final int WIDTH = 3; + static final int HEIGHT = 6; + static int[][] mat0 = new int[HEIGHT][WIDTH]; + + char answer; + int[][] mat1; + + public void run() throws IOException { + input(); + solve(); + print(); + } + + private void input() throws IOException { + getLine(); + for (int y = 0; y < HEIGHT; y++) { + for (int x = 0; x < WIDTH; x++) { + mat0[y][x] = Integer.parseInt(input.nextToken()); + } + } + } + + int[][] matches = new int[15][2]; + + private void solve() { + answer = '0'; + mat1 = new int[HEIGHT][WIDTH]; + + for (int index = 0, teamA = 0; teamA < TEAM_LEN; teamA++) { + for (int teamB = teamA + 1; teamB < TEAM_LEN; teamB++) { + matches[index][0] = teamA; + matches[index][1] = teamB; + index++; + } + } + + if (!precheck()) return; + answer = search(0) ? '1' : '0'; + } + + private boolean precheck() { + int sum = 0; + int win = 0, lose = 0; + int draw = 0; + + // 각 국가의 가로 합은 항상 5가 되어야 함 + for (int y = 0; y < HEIGHT; y++) { + int row = 0; + + for (int x = 0; x < WIDTH; x++) { + row += mat0[y][x]; + } + + win += mat0[y][0]; + draw += mat0[y][1]; + lose += mat0[y][2]; + + if (row != 5) return false; + sum += row; + } + + // 모든 숫자를 더했을때 값은 항상 30이 되어야 함 + if (sum != 30) return false; + + // 승이 15면 패가 15여야 함 (승의 합 == 패의 합) + // 누군가 이기면, 누군가 지는것이기 때문 + if (win != lose) return false; + + // 30 - (승) - (패) == (무)의 합이여 함 + if (30 - win - lose != draw) return false; + + return true; + } + + private boolean search(int match) { + // A - B : 승 + // A - C : 승 + // A - D : 승 + // A - D : 무 + // A - D : 패 + // A - C : 무 + // A - C : 패 + // A - B : 무 + // A - B : 패 + + if (match == 15) return true; + + int teamA = matches[match][0]; + int teamB = matches[match][1]; + + if (mat1[teamA][WIN] + 1 <= mat0[teamA][WIN] && mat1[teamB][LOSE] + 1 <= mat0[teamB][LOSE]){ + mat1[teamA][WIN]++; mat1[teamB][LOSE]++; + if (search(match + 1)) return true; + mat1[teamA][WIN]--; mat1[teamB][LOSE]--; + } + + if (mat1[teamA][DRAW] + 1 <= mat0[teamA][DRAW] && mat1[teamB][DRAW] + 1 <= mat0[teamB][DRAW]){ + mat1[teamA][DRAW]++; mat1[teamB][DRAW]++; + if (search(match + 1)) return true; + mat1[teamA][DRAW]--; mat1[teamB][DRAW]--; + } + + if (mat1[teamA][LOSE] + 1 <= mat0[teamA][LOSE] && mat1[teamB][WIN] + 1 <= mat0[teamB][WIN]){ + mat1[teamA][LOSE]++; mat1[teamB][WIN]++; + if (search(match + 1)) return true; + mat1[teamA][LOSE]--; mat1[teamB][WIN]--; + } + + return false; + } + + private void print() throws IOException { + writer.write(answer); + writer.write(" "); + } + + // ---------------------------------------------------------- + + private static void getLine() throws IOException { + input = new StringTokenizer(reader.readLine().trim()); + } +} From 032efdd036a9a6ac66dbe33c65e7c1e5f9f9c9f5 Mon Sep 17 00:00:00 2001 From: "YeJun, Jung" Date: Sun, 15 Feb 2026 18:42:43 +0900 Subject: [PATCH 08/12] feat: add boj p1931 solution --- problems/baekjoon/p1931/Main.java | 104 ++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 problems/baekjoon/p1931/Main.java diff --git a/problems/baekjoon/p1931/Main.java b/problems/baekjoon/p1931/Main.java new file mode 100644 index 0000000..e62653d --- /dev/null +++ b/problems/baekjoon/p1931/Main.java @@ -0,0 +1,104 @@ +/* + * (1931) 회의실 배정 + * https://www.acmicpc.net/problem/1931 + */ + +import java.io.*; +import java.util.*; + +/** + * Baekjoon - 회의실 배정 + * @author YeJun, Jung + * + * [분석] + * - 회의 시간이 겹치지 않도록 최대한 많은 회의에 참가한다. + * + * [전략] + * - 우선순위 큐를 사용해서 회의가 빨리 끝나는 순서로 참가한다. + * - 우선순위 큐 시간 복잡도 push, pop - O(logN) + */ +public class Main { + static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + static BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); + static StringTokenizer input; + + // ---------------------------------------------------------- + + public static void main(String[] args) throws IOException { + new Main().run(); + } + + // ---------------------------------------------------------- + + int answer; + int meetLen; + PriorityQueue meetQ; + int meetEndTime; + + public void run() throws IOException { + input(); + solve(); + print(); + } + + private void input() throws IOException { + meetLen = Integer.parseInt(reader.readLine().trim()); + + meetQ = new PriorityQueue<>((Meet a, Meet b) -> { + int c1 = Integer.compare(a.end, b.end); + if (c1 != 0) return c1; + + int c2 = Integer.compare(a.begin, b.begin); + return c2; + }); + + for (int index = 0; index < meetLen; index++) { + meetQ.offer(Meet.fromReader()); + } + } + + private void solve() { + meetEndTime = 0; + + while (!meetQ.isEmpty()) { + Meet peek = meetQ.poll(); + + if (meetEndTime <= peek.begin) { + meetEndTime = peek.end; + answer++; + } + } + } + + private void print() throws IOException { + writer.write(answer + "\n"); + writer.flush(); + } + + // ---------------------------------------------------------- + + private static class Meet { + int begin; + int end; + + public Meet(int begin, int end) { + this.begin = begin; + this.end = end; + } + + public static Meet fromReader() throws IOException { + getLine(); + + int begin = Integer.parseInt(input.nextToken()); + int end = Integer.parseInt(input.nextToken()); + + return new Meet(begin, end); + } + } + + // ---------------------------------------------------------- + + private static void getLine() throws IOException { + input = new StringTokenizer(reader.readLine().trim()); + } +} From 99a5380a1c944a4503e63ff8a5f2432f7ffde316 Mon Sep 17 00:00:00 2001 From: "YeJun, Jung" Date: Sun, 15 Feb 2026 18:44:58 +0900 Subject: [PATCH 09/12] add boj p2839 solution --- problems/baekjoon/p2839/Main.java | 70 +++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 problems/baekjoon/p2839/Main.java diff --git a/problems/baekjoon/p2839/Main.java b/problems/baekjoon/p2839/Main.java new file mode 100644 index 0000000..451a6df --- /dev/null +++ b/problems/baekjoon/p2839/Main.java @@ -0,0 +1,70 @@ +/* + * (2839) 설탕 배달 + * https://www.acmicpc.net/problem/2839 + */ + +import java.io.*; +import java.util.*; + +/** + * Baekjoon - 설탕 배달 + * @author YeJun, Jung + * + * [분석] + * - N kg의 설탕을 3kg, 5kg 봉지에 나누어 담을 때, 봉지의 개수를 최소화해야 한다. + * - 정확하게 N kg을 만들 수 없다면 -1을 출력한다. + * + * [전략] + * - 5kg 봉지의 개수(kg5)를 0부터 최대 가능한 수(num / 5)까지 순회하며 완전 탐색한다. + * - 남은 무게(num - 5 * kg5)가 3으로 나누어떨어지는지 확인한다. + * - 조건을 만족하는 경우 중 총 봉지 수(kg5 + kg3)의 최솟값을 answer에 갱신한다. + */ +public class Main { + static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + static BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); + + // ---------------------------------------------------------- + + public static void main(String[] args) throws IOException { + new Main().run(); + } + + // ---------------------------------------------------------- + + int answer; + int num; + + public void run() throws IOException { + input(); + solve(); + print(); + } + + private void input() throws IOException { + num = Integer.parseInt(reader.readLine().trim()); + } + + private void solve() { + answer = -1; + calc(); + } + + private void calc() { + int last = num / 5; + + for (int kg5 = 0; kg5 <= last; kg5++) { + int kg3 = num - 5 * kg5; + if (kg3 % 3 != 0) continue; + + int len = kg5 + (kg3 / 3); + if (answer < 0 || answer > len) answer = len; + } + } + + private void print() throws IOException { + writer.write(answer + "\n"); + writer.flush(); + } + + // ---------------------------------------------------------- +} From 8d8af7e1d7942b116bf4740806a9d79554bc5048 Mon Sep 17 00:00:00 2001 From: "YeJun, Jung" Date: Sun, 15 Feb 2026 19:49:09 +0900 Subject: [PATCH 10/12] feat: add boj p10816 solution --- problems/baekjoon/p10816/Main.java | 82 ++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 problems/baekjoon/p10816/Main.java diff --git a/problems/baekjoon/p10816/Main.java b/problems/baekjoon/p10816/Main.java new file mode 100644 index 0000000..8c42829 --- /dev/null +++ b/problems/baekjoon/p10816/Main.java @@ -0,0 +1,82 @@ +/* + * (10816) 숫자 카드 2 + * https://www.acmicpc.net/problem/10816 + */ + +import java.io.*; +import java.util.*; + +/** + * Baekjoon - 숫자 카드 2 + * @author YeJun, Jung + * + * [전략] + * - HashMap에 카드에 적힌 숫자를 Key, 개수를 Value로 저장 + * - 주어진 M개의 수개에 대해서 숫자 카드의 개수를 출력 + */ +public class Main { + static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + static BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); + static StringTokenizer input; + + // ---------------------------------------------------------- + + public static void main(String[] args) throws IOException { + new Main().run(); + } + + // ---------------------------------------------------------- + + int[] answer; + int cardLen; + Map cardMap; + + public void run() throws IOException { + input(); + solve(); + print(); + } + + private void input() throws IOException { + cardLen = Integer.parseInt(reader.readLine().trim()); + cardMap = new HashMap(); + + getLine(); + for (int index = 0; index < cardLen; index++) { + int num = Integer.parseInt(input.nextToken()); + + if (!cardMap.containsKey(num)) { + cardMap.put(num, 0); + } + + cardMap.put(num, cardMap.get(num) + 1); + } + } + + private void solve() throws IOException { + int N = Integer.parseInt(reader.readLine().trim()); + answer = new int[N]; + + getLine(); + for (int index = 0; index < N; index++) { + int target = Integer.parseInt(input.nextToken()); + + Integer count = cardMap.get(target); + answer[index] = count == null ? 0 : count; + } + } + + private void print() throws IOException { + for (int num : answer) { + writer.write(num + " "); + } + writer.write("\n"); + writer.flush(); + } + + // ---------------------------------------------------------- + + private static void getLine() throws IOException { + input = new StringTokenizer(reader.readLine().trim()); + } +} From dafdba5aa5b7faf60eb144754eadba956ca6dec5 Mon Sep 17 00:00:00 2001 From: "YeJun, Jung" Date: Sun, 15 Feb 2026 20:19:01 +0900 Subject: [PATCH 11/12] add boj p1654 solution --- problems/baekjoon/p1654/Main.java | 99 +++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 problems/baekjoon/p1654/Main.java diff --git a/problems/baekjoon/p1654/Main.java b/problems/baekjoon/p1654/Main.java new file mode 100644 index 0000000..dfcc2e0 --- /dev/null +++ b/problems/baekjoon/p1654/Main.java @@ -0,0 +1,99 @@ +/* + * (1654) 랜선 자르기 + * https://www.acmicpc.net/problem/1654 + */ + +import java.io.*; +import java.util.*; + +/** + * Baekjoon - 랜선 자르기 + * @author YeJun, Jung + * + * [전략] + * - 입력받은 랜선 중 최대값 ~ 0까지 이분탐색하면서 최적의 값을 찾아나간다. + * - 이분탐색을 통해 순차탐색보다 시간복잡도 O(logN)으로 최적의 길이를 찾을 수 있다. + */ +public class Main { + static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + static BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); + static StringTokenizer input; + + // ---------------------------------------------------------- + + public static void main(String[] args) throws IOException { + new Main().run(); + } + + // ---------------------------------------------------------- + + long answer; + int lineCount; + long needsLen; + long[] lineArr; + + public void run() throws IOException { + input(); + solve(); + print(); + } + + private void input() throws IOException { + getLine(); + lineCount = Integer.parseInt(input.nextToken()); + needsLen = Long.parseLong(input.nextToken()); + + lineArr = new long[lineCount]; + + for (int index = 0; index < lineCount; index++) { + lineArr[index] = Long.parseLong(reader.readLine().trim()); + } + } + + private void solve() { + answer = binarySearch(); + } + + private long binarySearch() { + long low = 1; + long mid = 0; + long high = lineArr[0]; + + for (int index = 1; index < lineCount; index++) { + if (lineArr[index] > high) high = lineArr[index]; + } + + while (low <= high) { + mid = (low + high) / 2; + + if (countSplitLine(mid) >= needsLen) { + low = mid + 1; + } else { + high = mid - 1; + } + } + + return high; + } + + private long countSplitLine(long value) { + long result = 0; + + for (long item : lineArr) { + result += item / value; + } + + return result; + } + + private void print() throws IOException { + writer.write(answer + "\n"); + writer.flush(); + } + + // ---------------------------------------------------------- + + private static void getLine() throws IOException { + input = new StringTokenizer(reader.readLine().trim()); + } +} From 43b5fc3fbee7c62be63b8dfb11a7a67477bbbbd3 Mon Sep 17 00:00:00 2001 From: "YeJun, Jung" Date: Sun, 15 Feb 2026 20:58:49 +0900 Subject: [PATCH 12/12] feat: add boj p1992 solution --- problems/baekjoon/p1992/Main.java | 91 +++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 problems/baekjoon/p1992/Main.java diff --git a/problems/baekjoon/p1992/Main.java b/problems/baekjoon/p1992/Main.java new file mode 100644 index 0000000..2a2d41e --- /dev/null +++ b/problems/baekjoon/p1992/Main.java @@ -0,0 +1,91 @@ +/* + * (1992) 쿼드트리 + * https://www.acmicpc.net/problem/1992 + */ + +import java.io.*; +import java.util.*; + +/** + * Baekjoon - 쿼드트리 + * @author YeJun, Jung + * + * [전략] + * - 압축 되어있는지 판다. + * - 주어진 범위의 문자가 모두 같으면 압축이 이미 되어 있는 것. + * - 주어진 범위를 사분면으로 쪼개서 차례대로 방문한다. + * - 압축 결과를 StringBuilder를 사용해서 합친다. + */ +public class Main { + static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); + static BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); + + // ---------------------------------------------------------- + + public static void main(String[] args) throws IOException { + new Main().run(); + } + + // ---------------------------------------------------------- + + int boardSize; + char[][] board; + String answer; + + public void run() throws IOException { + input(); + solve(); + print(); + } + + private void input() throws IOException { + boardSize = Integer.parseInt(reader.readLine().trim()); + board = new char[boardSize][boardSize]; + + for (int y = 0; y < boardSize; y++) { + board[y] = reader.readLine().trim().toCharArray(); + } + } + + private void solve() { + answer = compress(0, 0, boardSize - 1, boardSize - 1).toString(); + } + + private StringBuilder compress(int sx, int sy, int ex, int ey) { + int size = ex - sx + 1; + + if (size == 1 || isCompressed(sx, sy, ex, ey)) { + return new StringBuilder(String.valueOf(board[sy][sx])); + } + + int nSize = size / 2; + StringBuilder result = new StringBuilder(); + + result.append("("); + result.append(compress(sx, sy, sx + nSize - 1, sy + nSize - 1)); + result.append(compress(sx + nSize, sy, ex, sy + nSize - 1)); + result.append(compress(sx, sy + nSize, sx + nSize - 1, ey)); + result.append(compress(sx + nSize, sy + nSize, ex, ey)); + result.append(")"); + + return result; + } + + private boolean isCompressed(int sx, int sy, int ex, int ey) { + + for (int cy = sy; cy <= ey; cy++) { + for (int cx = sx; cx <= ex; cx++) { + if (board[cy][cx] != board[sy][sx]) return false; + } + } + return true; + } + + private void print() throws IOException { + writer.write(answer); + writer.write("\n"); + writer.flush(); + } + + // ---------------------------------------------------------- +}