From c7197b8c5b5502973b989d436433c8ab148bec27 Mon Sep 17 00:00:00 2001 From: Hwannee00 Date: Mon, 2 Feb 2026 14:47:50 +0900 Subject: [PATCH 01/20] =?UTF-8?q?BOJ=2016235=20=EB=82=98=EB=AC=B4=20?= =?UTF-8?q?=EC=9E=AC=ED=85=8C=ED=81=AC=20=ED=92=80=EC=9D=B4(=EA=B5=AC?= =?UTF-8?q?=ED=98=84)=20-=20=EB=B0=95=EC=9E=AC=ED=99=98[JAVA]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\354\236\254\355\205\214\355\201\254.java" | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 "java/src/feb/week1/boj/\353\202\230\353\254\264\354\236\254\355\205\214\355\201\254.java" diff --git "a/java/src/feb/week1/boj/\353\202\230\353\254\264\354\236\254\355\205\214\355\201\254.java" "b/java/src/feb/week1/boj/\353\202\230\353\254\264\354\236\254\355\205\214\355\201\254.java" new file mode 100644 index 0000000..d7a68d4 --- /dev/null +++ "b/java/src/feb/week1/boj/\353\202\230\353\254\264\354\236\254\355\205\214\355\201\254.java" @@ -0,0 +1,172 @@ +package feb.week1.boj; + +import java.util.*; +import java.io.*; + +public class 나무재테크 { + static BufferedReader br; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + init(); + br.close(); + } + + /** + * N x N + * 초기 모든 땅의 양분은 5만큼 있다. + * + * M 개의 나무를 구매해 땅에 심는다. + * - 같은 칸에 여러 개의 나무가 심어져 있을 수 있다. + * + * [봄] + * 자신의 나이만큼 양분을 먹고, 나이가 1 증가 + * - 한 칸에 여러 나무가 있다면, 어린 나무부터 양분을 먹는다. -> 양분을 먹지 못하면 즉사한다. + * + * [여름] + * 봄에 죽은 나무가 양분으로 변한다. + * - 죽은 나무의 나이 / 2 가 양분으로 추가된다. (소수점 X) + * + * [가을] + * 나무가 번식한다. (나이가 5배수 인 나무만) + * - 인접한 8개의 칸에 나이가 1인 나무가 생긴다. -> 격자를 벗어나면 나무가 생기지 않는다. + * + * [겨울] + * 각 칸에 A[r][c] 만큼 양분이 추가된다. + * + * => K년이 지난 이후 상도의 땅에 살아있는 나무의 개수를 구해라 + * + */ + static StringTokenizer st; + static int treeId; + static int n, m, k; + static int[][] map; + static int[][] a; + static Deque[][] trees; + static void init() throws IOException { + treeId = 0; + st = new StringTokenizer(br.readLine().trim()); + n = Integer.parseInt(st.nextToken()); // 격자의 크기 + m = Integer.parseInt(st.nextToken()); // 초기 나무의 수 + k = Integer.parseInt(st.nextToken()); // 시뮬레이션 횟수 + + map = new int[n][n]; + trees = new Deque[n][n]; + List[][] temp = new List[n][n]; // 정렬을 위해 임시로 사용하는 변수 + for(int x=0; x(); // Deque 생성 + temp[x][y] = new ArrayList<>(); + } + } + + a = new int[n][n]; + for(int x=0; x 0) { // 한 해씩 처리 + spring(); + summer(); + autumn(); + winter(); + } + int treeCount = 0; + for(int x=0; x[][] dead; + static void spring() { + dead = new List[n][n]; + for(int x=0; x cur = trees[x][y]; // 현재 처리할 나무 + Deque next = new ArrayDeque<>(); // 양분 흡수 가능한 나무 + dead[x][y] = new ArrayList<>(); // 죽는 나무 + // 나무가 있다면 + while(!cur.isEmpty()) { + int age = cur.pollFirst(); // 가장 어린 나무 + if(map[x][y] >= age) { + map[x][y] -= age; + next.offerLast(age+1); + } else { + dead[x][y].add(age); + } + } + trees[x][y] = next; + } + } + } + + static void summer() { + for (int x = 0; x < n; x++) { + for (int y = 0; y < n; y++) { + if(dead[x][y] == null) continue; + for (int age : dead[x][y]) { + map[x][y] += age / 2; + } + } + } + } + static int[] dx = {0,1,0,-1,1,1,-1,-1}; + static int[] dy = {1,0,-1,0,1,-1,1,-1}; + static void autumn() { + for(int x=0; x= n || ny >= n) continue; + trees[nx][ny].offerFirst(1); + } + } + } + } + } + + static void winter() { + for(int x=0; x Date: Mon, 2 Feb 2026 15:35:17 +0900 Subject: [PATCH 02/20] =?UTF-8?q?BOJ=2018428=20=EB=82=98=EB=AC=B4=20?= =?UTF-8?q?=EC=9E=AC=ED=85=8C=ED=81=AC=20=ED=92=80=EC=9D=B4(=EA=B5=AC?= =?UTF-8?q?=ED=98=84)=20-=20=EB=B0=95=EC=9E=AC=ED=99=98[PYTHON]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...4_\353\260\225\354\236\254\355\231\230.py" | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 "python/src/feb/week1/boj/\353\202\230\353\254\264\354\236\254\355\205\214\355\201\254_\353\260\225\354\236\254\355\231\230.py" diff --git "a/python/src/feb/week1/boj/\353\202\230\353\254\264\354\236\254\355\205\214\355\201\254_\353\260\225\354\236\254\355\231\230.py" "b/python/src/feb/week1/boj/\353\202\230\353\254\264\354\236\254\355\205\214\355\201\254_\353\260\225\354\236\254\355\231\230.py" new file mode 100644 index 0000000..85bcb90 --- /dev/null +++ "b/python/src/feb/week1/boj/\353\202\230\353\254\264\354\236\254\355\205\214\355\201\254_\353\260\225\354\236\254\355\231\230.py" @@ -0,0 +1,106 @@ +def solution(): + import sys + from collections import deque + input = sys.stdin.readline + + n, m, k = map(int, input().split()) + a = [list(map(int, input().split())) for _ in range(n)] + board = [[5] * n for _ in range(n)] + trees = [[deque() for _ in range(n)] for _ in range(n)] + temp = [[[] for _ in range(n)] for _ in range(n)] + for _ in range(m): + x, y, age = map(int, input().split()) + temp[x-1][y-1].append(age) + + for x in range(n): + for y in range(n): + if not temp[x][y]: # 나무가 없다면 넘어감 + continue + temp[x][y].sort() + trees[x][y] = deque(temp[x][y]) + + dead_tree = None + def spring(): + nonlocal trees, dead_tree + """ + 양분을 흡수한다. + if age <= map[x][y] : 양분 흡수 가능 + else : 즉사 + """ + dead_tree = [[[] for _ in range(n)] for _ in range(n)] + for x in range(n): + for y in range(n): + if not trees[x][y]: # 나무가 없다면 넘어감 + continue + # 나무가 있다면 + cur = trees[x][y] + next = deque() + + while cur: + age = cur.popleft() + if age <= board[x][y]: + next.append(age+1) + board[x][y] -= age + else: + dead_tree[x][y].append(age) + while cur: + dead_tree[x][y].append(cur.popleft()) + break + + trees[x][y] = next + + def summer(): + """ + dead_tree 를 기반으로 양분을 추가한다. + """ + for x in range(n): + for y in range(n): + if not dead_tree[x][y]: + continue + + for age in dead_tree[x][y]: + board[x][y] += (age//2) + + dx = [0,1,0,-1,1,1,-1,-1] + dy = [1,0,-1,0,1,-1,1,-1] + def autumn(): + for x in range(n): + for y in range(n): + if not trees[x][y]: # 나무가 없다면 넘어감 + continue + # 나무가 있다면 + for age in trees[x][y]: + if age%5 != 0: + continue + for dir in range(8): + nx = x + dx[dir] + ny = y + dy[dir] + if nx < 0 or ny < 0 or nx >= n or ny >= n: + continue + trees[nx][ny].appendleft(1) + + def winter(): + nonlocal board + """ + a 배열의 값을 누적 + """ + for x in range(n): + for y in range(n): + board[x][y] += a[x][y] + + for _ in range(k): + spring() + summer() + autumn() + winter() + + cnt = 0 + for x in range(n): + for y in range(n): + cnt += len(trees[x][y]) + + return cnt + + +if __name__ == '__main__': + print(solution()) \ No newline at end of file From caf5f2982c6a5479ffef0a2836dc18399c436773 Mon Sep 17 00:00:00 2001 From: Hwannee00 Date: Mon, 2 Feb 2026 19:00:42 +0900 Subject: [PATCH 03/20] =?UTF-8?q?CODETREE=20=EC=97=AC=EC=99=95=EA=B0=9C?= =?UTF-8?q?=EB=AF=B8=20=ED=92=80=EC=9D=B4(=EC=9D=B4=EB=B6=84=ED=83=90?= =?UTF-8?q?=EC=83=89)=20-=20=EB=B0=95=EC=9E=AC=ED=99=98[JAVA]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\353\260\225\354\236\254\355\231\230.java" | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 "java/src/feb/week1/codetree/\354\227\254\354\231\225\352\260\234\353\257\270_\353\260\225\354\236\254\355\231\230.java" diff --git "a/java/src/feb/week1/codetree/\354\227\254\354\231\225\352\260\234\353\257\270_\353\260\225\354\236\254\355\231\230.java" "b/java/src/feb/week1/codetree/\354\227\254\354\231\225\352\260\234\353\257\270_\353\260\225\354\236\254\355\231\230.java" new file mode 100644 index 0000000..f5581cf --- /dev/null +++ "b/java/src/feb/week1/codetree/\354\227\254\354\231\225\352\260\234\353\257\270_\353\260\225\354\236\254\355\231\230.java" @@ -0,0 +1,131 @@ +package feb.week1.codetree; + +import java.util.*; +import java.io.*; + +public class 여왕개미_박재환 { + static BufferedReader br; + static StringBuilder sb; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + sb = new StringBuilder(); + init(); + br.close(); + System.out.println(sb); + } + + /** + * 1차원 수직선으로 표현 (0 ~ 10**9) + * + * [마을건설] + * - 여왕개미 집을 x = 0 에 건설 + * - N개의 개미집 건설 (1~N번호를 가짐) + * - 번호가 큰 것이 더 큰 x 좌표를 가짐 + * + * [개미집 건설] + * - 건설할 개미집 위치는 p + * - p는 이제까지 지어진 집보다 큰 좌표로 주어짐 + * + * [개미집 철거] + * - q번 개미집을 철거 + * + * [개미집 정찰] + * - 정찰 나갈 개미의 수 r + * - 각 개미들은 출발할 개미집 선택 (여왕집도 가능) + * - 1초에 1만큼 x+1 이동 + * - 개미가 지나간 집은 안전한 개미집이 된다. -> 여왕 개미가 있는 곳은 항상 안전한 개미집 + * - 더 이상 전진할 수 없거나, 안전한 개미집을 만나면 이동을 멈춤 + * - 정찰에 걸리는 시간이 최소가 되도록 개미집 선택 + */ + static StringTokenizer st; + static void init() throws IOException { + int tc = Integer.parseInt(br.readLine().trim()); + while(tc-- > 0) { + st = new StringTokenizer(br.readLine().trim()); + int command = Integer.parseInt(st.nextToken()); + switch(command) { + case 100: { // 마을 건설 + buildVillage(); + break; + } + case 200: { // 개미집 건설 + buildNewHome(); + break; + } + case 300: { // 개미집 철거 + removeHome(); + break; + } + case 400: { // 개미집 정찰 + sb.append(reconnaissanceHome()).append('\n'); + break; + } + } + } + } + static int hIdx; + static TreeSet homeLocations; // 집 좌표 정보 저장 + static Map idToLocation; // id와 좌표정보 매핑 + static void buildVillage() { + hIdx = 0; + homeLocations = new TreeSet<>(Integer::compare); + idToLocation = new HashMap<>(); + // 여왕 집 + hIdx++; + int input = Integer.parseInt(st.nextToken()); + while(input-- > 0) { + int location = Integer.parseInt(st.nextToken()); + homeLocations.add(location); + idToLocation.put(hIdx++, location); + } + } + static void buildNewHome() { + int location = Integer.parseInt(st.nextToken()); + homeLocations.add(location); + idToLocation.put(hIdx++, location); + } + static void removeHome() { + int id = Integer.parseInt(st.nextToken()); + int location = idToLocation.get(id); + homeLocations.remove(location); + idToLocation.remove(id); + } + static int reconnaissanceHome() { + int antCount = Integer.parseInt(st.nextToken()); + + int l = 0, r = homeLocations.last(); + int minTime = r+1; + while(l <= r) { + int mid = l + (r-l)/2; + + if(canReconnaissance(antCount, mid)) { // 정찰이 가능한지 + minTime = Math.min(mid, minTime); + r = mid-1; + } else { + l = mid+1; + } + } + return minTime; + } + static boolean canReconnaissance(int antCount, int target) { + int prev = -1; + int next = -1; + for(int location : homeLocations) { + if(prev == -1) { // 아직 할당되지 않음 + prev = location; + next = location + target; + if(--antCount < 0) return false; + continue; + } + + // 이미 할당되어 있는 경우 + if(next < location) { + prev = location; + next = prev + target; + + if(--antCount < 0) return false; + } + } + return true; + } +} From 360ea4cfb0fe3bdf8d5d6bf87e380ddaac95b00b Mon Sep 17 00:00:00 2001 From: Hwannee00 Date: Mon, 2 Feb 2026 22:09:41 +0900 Subject: [PATCH 04/20] =?UTF-8?q?CODETREE=20=EC=97=AC=EC=99=95=EA=B0=9C?= =?UTF-8?q?=EB=AF=B8=20=EC=B5=9C=EC=A0=81=ED=99=94=20=ED=92=80=EC=9D=B4(?= =?UTF-8?q?=EC=9D=B4=EB=B6=84=ED=83=90=EC=83=89)=20-=20=EB=B0=95=EC=9E=AC?= =?UTF-8?q?=ED=99=98[JAVA]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\354\265\234\354\240\201\355\231\224.java" | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 "java/src/feb/week1/codetree/\354\227\254\354\231\225\352\260\234\353\257\270_\353\260\225\354\236\254\355\231\230_\354\265\234\354\240\201\355\231\224.java" diff --git "a/java/src/feb/week1/codetree/\354\227\254\354\231\225\352\260\234\353\257\270_\353\260\225\354\236\254\355\231\230_\354\265\234\354\240\201\355\231\224.java" "b/java/src/feb/week1/codetree/\354\227\254\354\231\225\352\260\234\353\257\270_\353\260\225\354\236\254\355\231\230_\354\265\234\354\240\201\355\231\224.java" new file mode 100644 index 0000000..5b6485a --- /dev/null +++ "b/java/src/feb/week1/codetree/\354\227\254\354\231\225\352\260\234\353\257\270_\353\260\225\354\236\254\355\231\230_\354\265\234\354\240\201\355\231\224.java" @@ -0,0 +1,123 @@ +package feb.week1.codetree; + +import java.util.*; +import java.io.*; + +public class 여왕개미_박재환_최적화 { + static BufferedReader br; + static StringBuilder sb; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + sb = new StringBuilder(); + init(); + br.close(); + System.out.println(sb); + } + + /** + * 1차원 수직선으로 표현 (0 ~ 10**9) + * + * [마을건설] + * - 여왕개미 집을 x = 0 에 건설 + * - N개의 개미집 건설 (1~N번호를 가짐) + * - 번호가 큰 것이 더 큰 x 좌표를 가짐 + * + * [개미집 건설] + * - 건설할 개미집 위치는 p + * - p는 이제까지 지어진 집보다 큰 좌표로 주어짐 + * + * [개미집 철거] + * - q번 개미집을 철거 + * + * [개미집 정찰] + * - 정찰 나갈 개미의 수 r + * - 각 개미들은 출발할 개미집 선택 (여왕집도 가능) + * - 1초에 1만큼 x+1 이동 + * - 개미가 지나간 집은 안전한 개미집이 된다. -> 여왕 개미가 있는 곳은 항상 안전한 개미집 + * - 더 이상 전진할 수 없거나, 안전한 개미집을 만나면 이동을 멈춤 + * - 정찰에 걸리는 시간이 최소가 되도록 개미집 선택 + */ + static StringTokenizer st; + static void init() throws IOException { + int tc = Integer.parseInt(br.readLine().trim()); + while(tc-- > 0) { + st = new StringTokenizer(br.readLine().trim()); + int command = Integer.parseInt(st.nextToken()); + switch(command) { + case 100: { // 마을 건설 + buildVillage(); + break; + } + case 200: { // 개미집 건설 + buildNewHome(); + break; + } + case 300: { // 개미집 철거 + removeHome(); + break; + } + case 400: { // 개미집 정찰 + sb.append(reconnaissanceHome()).append('\n'); + break; + } + } + } + } + static List homes; + static void buildVillage() { + homes = new ArrayList<>(); + int input = Integer.parseInt(st.nextToken()); + // 여왕개미 집 + homes.add(new AntHome(0)); + while (input-- > 0) { + int location = Integer.parseInt(st.nextToken()); + homes.add(new AntHome(location)); + } + } + static class AntHome { + int location; + boolean removed; + + AntHome(int location) { + this.location = location; + this.removed = false; + } + } + static void buildNewHome() { + int location = Integer.parseInt(st.nextToken()); + homes.add(new AntHome(location)); + } + static void removeHome() { + int id = Integer.parseInt(st.nextToken()); + homes.get(id).removed = true; // soft delete -> 인덱스 정보를 유지 + } + static int reconnaissanceHome() { + int antCount = Integer.parseInt(st.nextToken()); + + int l = 0, r = 1_000_000_000; // 0 ~ 10**9 + int minTime = r+1; + while(l <= r) { + int mid = l + (r-l)/2; + + if(canReconnaissance(antCount, mid)) { // 정찰이 가능한지 + minTime = Math.min(mid, minTime); + r = mid-1; + } else { + l = mid+1; + } + } + return minTime; + } + static boolean canReconnaissance(int antCount, int target) { + int lastLocation = -1_000_000_005; + for(int i=1; i lastLocation) { + lastLocation = home.location + target; + if(--antCount < 0) return false; + } + } + return true; + } +} From 8d4d6e25119bcfed0787daa1bef93e33e12138a2 Mon Sep 17 00:00:00 2001 From: Hwannee00 Date: Mon, 2 Feb 2026 23:00:56 +0900 Subject: [PATCH 05/20] =?UTF-8?q?SWAE=20=EC=A0=90=EC=8B=AC=EC=8B=9D?= =?UTF-8?q?=EC=82=AC=EC=8B=9C=EA=B0=84=20=ED=92=80=EC=9D=B4=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\353\260\225\354\236\254\355\231\230.java" | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 "java/src/feb/week1/swea/\354\240\220\354\213\254\354\213\235\354\202\254\354\213\234\352\260\204_\353\260\225\354\236\254\355\231\230.java" diff --git "a/java/src/feb/week1/swea/\354\240\220\354\213\254\354\213\235\354\202\254\354\213\234\352\260\204_\353\260\225\354\236\254\355\231\230.java" "b/java/src/feb/week1/swea/\354\240\220\354\213\254\354\213\235\354\202\254\354\213\234\352\260\204_\353\260\225\354\236\254\355\231\230.java" new file mode 100644 index 0000000..2984b5d --- /dev/null +++ "b/java/src/feb/week1/swea/\354\240\220\354\213\254\354\213\235\354\202\254\354\213\234\352\260\204_\353\260\225\354\236\254\355\231\230.java" @@ -0,0 +1,51 @@ +package feb.week1.swea; + +import java.util.*; +import java.io.*; + +public class 점심식사시간_박재환 { + static BufferedReader br; + static StringBuilder sb; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + sb = new StringBuilder(); + int tc = Integer.parseInt(br.readLine().trim()); + for(int i=1; i 각 사람이 계단을 선택하는 경우 2**10 => 1024 + * + */ + static StringTokenizer st; + static int n; + static int[][] map; + static void init() throws IOException { + n = Integer.parseInt(br.readLine().trim()); + map = new int[n][n]; + for(int x=0; x Date: Tue, 3 Feb 2026 18:55:21 +0900 Subject: [PATCH 06/20] =?UTF-8?q?BOJ=2016236=20=EC=95=84=EA=B8=B0=EC=83=81?= =?UTF-8?q?=EC=96=B4=20=ED=92=80=EC=9D=B4(BFS)=20-=20=EB=B0=95=EC=9E=AC?= =?UTF-8?q?=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\353\260\225\354\236\254\355\231\230.java" | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 "java/src/feb/week1/boj/\354\225\204\352\270\260\354\203\201\354\226\264_\353\260\225\354\236\254\355\231\230.java" diff --git "a/java/src/feb/week1/boj/\354\225\204\352\270\260\354\203\201\354\226\264_\353\260\225\354\236\254\355\231\230.java" "b/java/src/feb/week1/boj/\354\225\204\352\270\260\354\203\201\354\226\264_\353\260\225\354\236\254\355\231\230.java" new file mode 100644 index 0000000..415da7f --- /dev/null +++ "b/java/src/feb/week1/boj/\354\225\204\352\270\260\354\203\201\354\226\264_\353\260\225\354\236\254\355\231\230.java" @@ -0,0 +1,131 @@ +package feb.week1.boj; + +import java.util.*; +import java.io.*; + +public class 아기상어_박재환 { + static BufferedReader br; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + init(); + br.close(); + } + + /** + * N x N + * 물고기 M 마리와 아기상어 1마리가 있다. + * + * 초기 아기상어 크기는 2 + * 1초에 상하좌우 한 칸 씩 이동 + * + * 자기보다 큰 물고기가 있는 칸으로 지나갈 수 없다 + * 자기보다 작은 물고기만 먹을 수 있다 + * + * 더 이상 먹을 수 있는 물고기가 공간에 없다면 -> 엄마한테 도움 + * 먹을 수 있는 물고기가 1마리 -> 이동 + * 여러마리 -> 가장 가까운 물고기 먹으러 이동 + * - 지나가는 칸의 개수 + * - 가까운 물고기가 많다면 가장 위, 가장 왼쪽 물고기 + * + * 물고기를 먹으면 그 칸은 빈칸이 된다. + * 자신의 크기와 같은 수의 물고기를 먹을 때마다 크기가 1 증가한다. + */ + static StringTokenizer st; + static int n; + static int[][] map; + static Shark shark; + static void init() throws IOException { + n = Integer.parseInt(br.readLine().trim()); + map = new int[n][n]; + for(int x=0; x pq; + static int solution() { + pq = new PriorityQueue<>((a, b) -> { + if(a.dist != b.dist) return Integer.compare(a.dist, b.dist); + if(a.x != b.x) return Integer.compare(a.x, b.x); + return Integer.compare(a.y, b.y); + }); + int totalTime = 0; + while (findFish()) { + // 먹을 수 있는 물고기가 있는 경우 + Fish target = pq.poll(); + totalTime += target.dist; + shark.eat(); + shark.x = target.x; + shark.y = target.y; + + } + return totalTime; + } + + static int[] dx = {0,1,0,-1}; + static int[] dy = {1,0,-1,0}; + static boolean findFish() { + pq.clear(); // 우선순위 큐 초기화 + + Queue q = new ArrayDeque<>(); + boolean[][] visited = new boolean[n][n]; + + q.offer(new int[] {shark.x, shark.y, 0}); + visited[shark.x][shark.y] = true; + map[shark.x][shark.y] = 0; + while(!q.isEmpty()) { + int[] cur = q.poll(); + int x = cur[0]; + int y = cur[1]; + int dist = cur[2]; + + for(int dir=0; dir<4; dir++) { + int nx = x + dx[dir]; + int ny = y + dy[dir]; + if(nx < 0 || ny < 0 || nx >= n || ny >= n) continue; + if(visited[nx][ny] || map[nx][ny] > shark.size) continue; + visited[nx][ny] = true; + q.offer(new int[] {nx, ny, dist+1}); + if(map[nx][ny] > 0 && map[nx][ny] < shark.size) pq.offer(new Fish(nx, ny, dist+1)); + } + } + + return !pq.isEmpty(); // 먹을 수 있는 물고기 후보가 있다면 true, 없다면 false + } + + static class Fish { + int x, y; + int dist; + Fish(int x, int y, int dist) { + this.x = x; + this.y = y; + this.dist = dist; + } + } + + static class Shark { + int x, y; + int size; + int eat; + + Shark(int x, int y) { + this.x = x; + this.y = y; + this.size = 2; + this.eat = 0; + } + + void eat() { + eat = eat + 1; + if(eat == size) { + size++; + eat = 0; + } + } + } +} From 730f9188a0a9adf2bc0626a7a9534fb680d862d4 Mon Sep 17 00:00:00 2001 From: Hwannee00 Date: Tue, 3 Feb 2026 19:32:58 +0900 Subject: [PATCH 07/20] =?UTF-8?q?BOJ=2016236=20=EC=95=84=EA=B8=B0=EC=83=81?= =?UTF-8?q?=EC=96=B4=20=ED=92=80=EC=9D=B4(BFS)=20-=20=EB=B0=95=EC=9E=AC?= =?UTF-8?q?=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...4_\353\260\225\354\236\254\355\231\230.py" | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 "python/src/feb/week1/boj/\354\225\204\352\270\260\354\203\201\354\226\264_\353\260\225\354\236\254\355\231\230.py" diff --git "a/python/src/feb/week1/boj/\354\225\204\352\270\260\354\203\201\354\226\264_\353\260\225\354\236\254\355\231\230.py" "b/python/src/feb/week1/boj/\354\225\204\352\270\260\354\203\201\354\226\264_\353\260\225\354\236\254\355\231\230.py" new file mode 100644 index 0000000..066972c --- /dev/null +++ "b/python/src/feb/week1/boj/\354\225\204\352\270\260\354\203\201\354\226\264_\353\260\225\354\236\254\355\231\230.py" @@ -0,0 +1,78 @@ +def solution(): + import sys + input = sys.stdin.readline + + n = int(input().strip()) + board = [list(map(int, input().split())) for _ in range(n)] + # 상어 위치 정하기 + shark = None + for x in range(n): + if not shark == None: + break + for y in range(n): + if board[x][y] == 9: + shark = [x, y, 2, 0] + break + + dx = [0,1,0,-1] + dy = [1,0,-1,0] + def find_fish(): + from collections import deque + q = deque() + visited = [[False] * n for _ in range(n)] + fish = None + + q.append((shark[0], shark[1], 0)) + visited[shark[0]][shark[1]] = True + board[shark[0]][shark[1]] = 0 + while q: + x, y, dist = q.popleft() + if not fish == None: + if dist > fish[2]: + continue + for dir in range(4): + nx = x + dx[dir] + ny = y + dy[dir] + + if nx < 0 or ny < 0 or nx >= n or ny >= n: + continue + if visited[nx][ny] or board[nx][ny] > shark[2]: + continue + visited[nx][ny] = True + q.append((nx, ny, dist+1)) + # 먹을 수 있는 물고기인지 + if board[nx][ny] > 0 and board[nx][ny] < shark[2]: + if fish == None: + fish = [nx, ny, dist+1] + elif fish[2] > dist+1: + fish = [nx, ny, dist+1] + elif fish[2] == dist+1 and fish[0] > nx: + fish = [nx, ny, dist + 1] + elif fish[2] == dist + 1 and fish[0] == nx and fish[1] > ny: + fish = [nx, ny, dist + 1] + return fish + + total_time = 0 + while True: + fish = find_fish() + if fish == None: + break + x, y, dist = fish + total_time += dist + + sx, sy, ss, se = shark + sx = x + sy = y + se += 1 + if se == ss: + se = 0 + ss += 1 + shark = [sx, sy, ss, se] + + return total_time + + + + +if __name__ == '__main__': + print(solution()) \ No newline at end of file From 64613aed432f9a0c3bce2085aa7cae05803928e7 Mon Sep 17 00:00:00 2001 From: Hwannee00 Date: Wed, 4 Feb 2026 11:08:17 +0900 Subject: [PATCH 08/20] =?UTF-8?q?BOJ=2019238=20=EC=8A=A4=ED=83=80=ED=8A=B8?= =?UTF-8?q?=20=ED=83=9D=EC=8B=9C=20=ED=92=80=EC=9D=B4(BFS=20+=20=EC=8B=9C?= =?UTF-8?q?=EB=AE=AC=EB=A0=88=EC=9D=B4=EC=85=98)=20-=20=EB=B0=95=EC=9E=AC?= =?UTF-8?q?=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\353\260\225\354\236\254\355\231\230.java" | 230 ++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 "java/src/feb/week1/boj/\354\212\244\355\203\200\355\212\270\355\203\235\354\213\234_\353\260\225\354\236\254\355\231\230.java" diff --git "a/java/src/feb/week1/boj/\354\212\244\355\203\200\355\212\270\355\203\235\354\213\234_\353\260\225\354\236\254\355\231\230.java" "b/java/src/feb/week1/boj/\354\212\244\355\203\200\355\212\270\355\203\235\354\213\234_\353\260\225\354\236\254\355\231\230.java" new file mode 100644 index 0000000..bef5ee6 --- /dev/null +++ "b/java/src/feb/week1/boj/\354\212\244\355\203\200\355\212\270\355\203\235\354\213\234_\353\260\225\354\236\254\355\231\230.java" @@ -0,0 +1,230 @@ +package feb.week1.boj; + +import java.util.*; +import java.io.*; + +public class 스타트택시_박재환 { + static BufferedReader br; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + init(); + br.close(); + } + /** + * 손님을 도착지로 데려다줄 때마다 연료가 충전된다. -> 승객을 태워 이동하면서 소모한 연료양의 두 배 만큼 + * 연료가 바닥나면 업무가 끝난다. + * + * M명의 승객을 태우는 것이 목표 + * N x N 격자 + * - 비어있음 + * - 벽이 있음 + * + * 택시는 상하좌우 인접한 빈 칸 하나로 이동 가능 + * -> 늘 최단경로로만 움직임 + * + * => 목적지 도착과, 연료 바닥이 동시에 나면, 이는 실패로 간주하지 않음 + */ + static StringTokenizer st; + static int n, m; + static int[][] map; + static Taxi taxi; + static Customer[] customers; + static void init() throws IOException { + st = new StringTokenizer(br.readLine().trim()); + n = Integer.parseInt(st.nextToken()); // 격자 크기 + m = Integer.parseInt(st.nextToken()); // 목표 손님 수 + int fuel = Integer.parseInt(st.nextToken()); // 초기 연료 + map = new int[n][n]; + for(int x=0; x q = new ArrayDeque<>(); + boolean[][] visited = new boolean[n][n]; + int[] foundCustomer = new int[3]; + foundCustomer[0] = n+1; + foundCustomer[1] = n+1; + foundCustomer[2] = n*n+1; + // 만약 택시 위치에 손님이 있다면 + if(map[taxi.x][taxi.y] > 0) { + int customerId = map[taxi.x][taxi.y]-1; + customers[customerId].distFromTaxi = 0; + return customerId; + } + // 택시위치 초기화 + q.offer(new int[] {taxi.x, taxi.y, 0}); + visited[taxi.x][taxi.y] = true; + + while(!q.isEmpty()) { + int[] cur = q.poll(); + int x = cur[0]; + int y = cur[1]; + int dist = cur[2]; + if(dist > foundCustomer[2]) break; + for(int dir=0; dir<4; dir++) { + int nx = x + dx[dir]; + int ny = y + dy[dir]; + if(nx < 0 || ny < 0 || nx >= n || ny >= n) continue; + if(visited[nx][ny] || map[nx][ny] == -1) continue; + // 현재 위치에 손님이 있는지 확인 + if(map[nx][ny] > 0) { + if(foundCustomer[0] == n+1 && foundCustomer[1] == n+1 && foundCustomer[2] == n*n+1) { + foundCustomer[0] = nx; + foundCustomer[1] = ny; + foundCustomer[2] = dist+1; + } else { + if(foundCustomer[2] > dist+1) { + foundCustomer[0] = nx; + foundCustomer[1] = ny; + foundCustomer[2] = dist+1; + } else if(foundCustomer[2] == dist+1 && foundCustomer[0] > nx) { + foundCustomer[0] = nx; + foundCustomer[1] = ny; + } else if(foundCustomer[2] == dist+1 && foundCustomer[0] == nx && foundCustomer[1] > ny) { + foundCustomer[1] = ny; + } + } + } + visited[nx][ny] = true; + q.offer(new int[] {nx, ny, dist+1}); + } + } + + if(foundCustomer[0] == n+1 && foundCustomer[1] == n+1 && foundCustomer[2] == n*n+1) return -1; + int customerId = map[foundCustomer[0]][foundCustomer[1]]-1; + customers[customerId].distFromTaxi = foundCustomer[2]; + return customerId; + } + static int getDistToEnd(Customer customer) { + Queue q = new ArrayDeque<>(); + boolean[][] visited = new boolean[n][n]; + + int sx = customer.sx, sy = customer.sy; + int ex = customer.ex, ey = customer.ey; + q.offer(new int[] {sx, sy, 0}); + visited[sx][sy] = true; + + while(!q.isEmpty()) { + int[] cur = q.poll(); + int x = cur[0]; + int y = cur[1]; + int dist = cur[2]; + + if(x == ex && y == ey) return dist; + + for(int dir=0; dir<4; dir++) { + int nx = x + dx[dir]; + int ny = y + dy[dir]; + if(nx < 0 || ny < 0 || nx >= n || ny >= n) continue; + if(visited[nx][ny] || map[nx][ny] == -1) continue; + visited[nx][ny] = true; + q.offer(new int[] {nx, ny, dist+1}); + } + } + + return -1; + } +} +/* +6 3 15 +0 0 1 0 0 0 +0 0 1 0 0 0 +0 0 0 0 0 0 +0 0 0 0 0 0 +0 0 0 0 1 0 +0 0 0 1 0 0 +6 5 +2 2 5 6 +5 4 1 6 +4 2 6 5 + +14 + */ From 2bdeb9a2913fbcf9bde93c97ed3063443912b6e1 Mon Sep 17 00:00:00 2001 From: Hwannee00 Date: Wed, 4 Feb 2026 11:56:18 +0900 Subject: [PATCH 09/20] =?UTF-8?q?BOJ=2019238=20=EC=8A=A4=ED=83=80=ED=8A=B8?= =?UTF-8?q?=20=ED=83=9D=EC=8B=9C=20=ED=92=80=EC=9D=B4(BFS)=20-=20=EB=B0=95?= =?UTF-8?q?=EC=9E=AC=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...4_\353\260\225\354\236\254\355\231\230.py" | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 "python/src/feb/week1/boj/\354\212\244\355\203\200\355\212\270\355\203\235\354\213\234_\353\260\225\354\236\254\355\231\230.py" diff --git "a/python/src/feb/week1/boj/\354\212\244\355\203\200\355\212\270\355\203\235\354\213\234_\353\260\225\354\236\254\355\231\230.py" "b/python/src/feb/week1/boj/\354\212\244\355\203\200\355\212\270\355\203\235\354\213\234_\353\260\225\354\236\254\355\231\230.py" new file mode 100644 index 0000000..ec59d3b --- /dev/null +++ "b/python/src/feb/week1/boj/\354\212\244\355\203\200\355\212\270\355\203\235\354\213\234_\353\260\225\354\236\254\355\231\230.py" @@ -0,0 +1,115 @@ +def solution(): + import sys + input = sys.stdin.readline + + n, m, fuel = map(int, input().split()) + board = list(list(map(int, input().split())) for _ in range(n)) + for x in range(n): + for y in range(n): + if board[x][y] == 1: + board[x][y] = -1 + + tx, ty = map(int, input().split()) + taxi = [tx-1, ty-1, fuel, 0] # x, y, 남은 연료, 태운 손님 + + customers = [] + for i in range(m): + sx, sy, ex, ey = map(int, input().split()) + customers.append([sx-1, sy-1, ex-1, ey-1]) + board[sx-1][sy-1] = i+1 + + dx = [-1, 0, 1, 0] + dy = [0, 1, 0, -1] + + def find_near_customer(): + from collections import deque + visited = [[False] * n for _ in range(n)] + q = deque() + + # 시작 위치 + q.append((taxi[0], taxi[1])) + visited[taxi[0]][taxi[1]] = True + + dist = 0 + while q: + size = len(q) + candidates = [] + + for _ in range(size): + x, y = q.popleft() + + if board[x][y] > 0: + candidates.append((x, y)) + + for d in range(4): + nx = x + dx[d] + ny = y + dy[d] + + if nx < 0 or ny < 0 or nx >= n or ny >= n: + continue + if visited[nx][ny] or board[nx][ny] == -1: + continue + + visited[nx][ny] = True + q.append((nx, ny)) + + if candidates: + candidates.sort() # 행 → 열 우선 + cx, cy = candidates[0] + return board[cx][cy] - 1, dist + + dist += 1 + + return -1, -1 + def get_dist_to_end(customer_id): + from collections import deque + q = deque() + visited = [[False] * n for _ in range(n)] + + sx, sy, ex, ey = customers[customer_id] + q.append((sx, sy, 0)) + visited[sx][sy] = True + + while q: + x, y, dist = q.popleft() + if x == ex and y == ey: + return dist + for dir in range(4): + nx = x + dx[dir] + ny = y + dy[dir] + + if nx < 0 or ny < 0 or nx >= n or ny >= n: + continue + if visited[nx][ny] or board[nx][ny] == -1: + continue + visited[nx][ny] = True + q.append((nx, ny, dist + 1)) + return -1 + + while True: + customer_id, c_dist = find_near_customer() + if customer_id == -1: + break + + # 손님을 찾았다면 + # 손님의 출발지까지 이동가능한지 + if taxi[2] < c_dist: + break + taxi[2] -= c_dist + taxi[0] = customers[customer_id][0] + taxi[1] = customers[customer_id][1] + board[customers[customer_id][0]][customers[customer_id][1]] = 0 + + dist_to_end = get_dist_to_end(customer_id) + if dist_to_end == -1 or dist_to_end > taxi[2]: + break + taxi[2] -= dist_to_end + taxi[0] = customers[customer_id][2] + taxi[1] = customers[customer_id][3] + taxi[2] += dist_to_end * 2 + taxi[3] += 1 + + return taxi[2] if taxi[3] == m else -1 + +if __name__ == '__main__': + print(solution()) \ No newline at end of file From 9e6bd7c553bddf5d436b5f9d6d9b29da72f61a5d Mon Sep 17 00:00:00 2001 From: Hwannee00 Date: Wed, 4 Feb 2026 13:18:53 +0900 Subject: [PATCH 10/20] =?UTF-8?q?CODETREE=20=ED=95=B4=EC=A0=81=20=EC=84=A0?= =?UTF-8?q?=EC=9E=A5=20=EC=BD=94=EB=94=94=20=ED=92=80=EC=9D=B4(TreeSet=20+?= =?UTF-8?q?=20PQ=20+=20HASHMAP)=20-=20=EB=B0=95=EC=9E=AC=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\353\260\225\354\236\254\355\231\230.java" | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 "java/src/feb/week1/codetree/\355\225\264\354\240\201\354\204\240\354\236\245\354\275\224\353\224\224_\353\260\225\354\236\254\355\231\230.java" diff --git "a/java/src/feb/week1/codetree/\355\225\264\354\240\201\354\204\240\354\236\245\354\275\224\353\224\224_\353\260\225\354\236\254\355\231\230.java" "b/java/src/feb/week1/codetree/\355\225\264\354\240\201\354\204\240\354\236\245\354\275\224\353\224\224_\353\260\225\354\236\254\355\231\230.java" new file mode 100644 index 0000000..5de4237 --- /dev/null +++ "b/java/src/feb/week1/codetree/\355\225\264\354\240\201\354\204\240\354\236\245\354\275\224\353\224\224_\353\260\225\354\236\254\355\231\230.java" @@ -0,0 +1,165 @@ +package feb.week1.codetree; + +import java.util.*; +import java.io.*; + +public class 해적선장코디_박재환 { + static BufferedReader br; + static StringBuilder sb; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + sb = new StringBuilder(); + init(); + br.close(); + System.out.println(sb); + } + static StringTokenizer st; + static TreeSet readyBattleShips; + static PriorityQueue waitBattleShips; + static Map bindBattleShips; + static void init() throws IOException { + int commandCount = Integer.parseInt(br.readLine().trim()); + int time = 0; + while(commandCount-- > 0) { + st = new StringTokenizer(br.readLine().trim()); + int command = Integer.parseInt(st.nextToken()); + switch(command) { + case 100: { + /** + * [공격 준비] + * N척의 선박에 사격 준비 지시 + * 선발 (id, 공격력, 재장전 시간, 상태 - 초기 상태는 사격 대기) + */ + readyAttack(); + break; + } + case 200: { + /** + * [지원 요청] + * 새로운 선박 합류 + */ + addNewBattleShip(); + break; + } + case 300: { + /** + * [함포 교체] + * id번 선박의 함포를 교체한다. (공격력 변경) + */ + changeCanon(); + break; + } + case 400: { + /** + * [공격 명령] + * 사격 대기 상태인 선박 중 공격력이 가장 높은 5척이 공격한다. + * - 공격력이 같다면 id가 낮은 것이 우선순위를 갖는다. + * - 사격 후 즉시 재장전에 들어간다. -> 사격 시점을 포함해 r 시간이 경과하면 사격 대기 상태로 변한다. + * + * => 총 피해량, 사격에 참여한 선박 수, 우선순위 id + */ + sb.append(attack(time)).append('\n'); + break; + } + } + /** + * 재장전 시간 감소 + */ + time++; + while(!waitBattleShips.isEmpty() && waitBattleShips.peek().remainShoot <= time) { + BattleShip battleShip = waitBattleShips.poll(); + readyBattleShips.add(battleShip); + } + } + } + static class BattleShip { + int id; + int pw; + int reload; + int remainShoot; + + BattleShip(int id, int pw, int reload) { + this.id = id; + this.pw = pw; + this.reload = reload; + + this.remainShoot = 0; // 초기에는 무조건 쏠 수 있도록 최소 값 + } + + int shoot(int time) { + this.remainShoot = this.reload + time; + return this.pw; + } + } + /** + * [공격 준비] + */ + static void readyAttack() { + bindBattleShips = new HashMap<>(); + waitBattleShips = new PriorityQueue<>((a, b) -> Integer.compare(a.remainShoot, b.remainShoot)); + readyBattleShips = new TreeSet<>((a, b) -> { + if(a.pw != b.pw) return Integer.compare(b.pw, a.pw); // 2. 공격력이 쎈 함선이 우선 + return Integer.compare(a.id, b.id); // id 가 작은 함선이 우선 + }); + + int battleShipCount = Integer.parseInt(st.nextToken()); + while(battleShipCount-- > 0) { + int id = Integer.parseInt(st.nextToken()); + int pw = Integer.parseInt(st.nextToken()); + int reload = Integer.parseInt(st.nextToken()); + BattleShip battleShip = new BattleShip(id, pw, reload); + readyBattleShips.add(battleShip); + bindBattleShips.put(id, battleShip); + } + } + /** + * [지원 요청] + */ + static void addNewBattleShip() { + int id = Integer.parseInt(st.nextToken()); + int pw = Integer.parseInt(st.nextToken()); + int reload = Integer.parseInt(st.nextToken()); + BattleShip battleShip = new BattleShip(id, pw, reload); + readyBattleShips.add(battleShip); + bindBattleShips.put(id, battleShip); + } + /** + * [함포 교체] + */ + static void changeCanon() { + int id = Integer.parseInt(st.nextToken()); + int pw = Integer.parseInt(st.nextToken()); + + BattleShip battleShip = bindBattleShips.get(id); + if(readyBattleShips.remove(battleShip)) { + battleShip.pw = pw; + readyBattleShips.add(battleShip); + } else { + battleShip.pw = pw; + } + } + /** + * [공격 명령] + */ + static String attack(int time) { + List shootList = new ArrayList<>(); + + for(BattleShip battleShip : readyBattleShips) { + shootList.add(battleShip); + if(shootList.size() == 5) break; // 최대 5개의 함선만 사격 + } + + // 업데이트 + StringBuilder shootSb = new StringBuilder(); + shootSb.append(' ').append(shootList.size()).append(' '); + int totalPw = 0; + for(BattleShip battleShip : shootList) { + readyBattleShips.remove(battleShip); + totalPw += battleShip.shoot(time); + shootSb.append(battleShip.id).append(' '); + waitBattleShips.add(battleShip); + } + shootSb.insert(0, totalPw); + return shootSb.toString(); + } +} From ed2fc986cdfb397e5c861b8881edf8e928eaa693 Mon Sep 17 00:00:00 2001 From: Hwannee00 Date: Wed, 4 Feb 2026 13:18:53 +0900 Subject: [PATCH 11/20] =?UTF-8?q?SWEA=20=EB=AF=B8=EC=83=9D=EB=AC=BC=20?= =?UTF-8?q?=EA=B2=A9=EB=A6=AC=20=ED=92=80=EC=9D=B4(=EC=8B=9C=EB=AE=AC?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=85=98)=20-=20=EB=B0=95=EC=9E=AC=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\353\260\225\354\236\254\355\231\230.java" | 165 ++++++++++++++++++ ...\353\260\225\354\236\254\355\231\230.java" | 131 ++++++++++++++ 2 files changed, 296 insertions(+) create mode 100644 "java/src/feb/week1/codetree/\355\225\264\354\240\201\354\204\240\354\236\245\354\275\224\353\224\224_\353\260\225\354\236\254\355\231\230.java" create mode 100644 "java/src/feb/week1/swea/\353\257\270\354\203\235\353\254\274\352\262\251\353\246\254_\353\260\225\354\236\254\355\231\230.java" diff --git "a/java/src/feb/week1/codetree/\355\225\264\354\240\201\354\204\240\354\236\245\354\275\224\353\224\224_\353\260\225\354\236\254\355\231\230.java" "b/java/src/feb/week1/codetree/\355\225\264\354\240\201\354\204\240\354\236\245\354\275\224\353\224\224_\353\260\225\354\236\254\355\231\230.java" new file mode 100644 index 0000000..5de4237 --- /dev/null +++ "b/java/src/feb/week1/codetree/\355\225\264\354\240\201\354\204\240\354\236\245\354\275\224\353\224\224_\353\260\225\354\236\254\355\231\230.java" @@ -0,0 +1,165 @@ +package feb.week1.codetree; + +import java.util.*; +import java.io.*; + +public class 해적선장코디_박재환 { + static BufferedReader br; + static StringBuilder sb; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + sb = new StringBuilder(); + init(); + br.close(); + System.out.println(sb); + } + static StringTokenizer st; + static TreeSet readyBattleShips; + static PriorityQueue waitBattleShips; + static Map bindBattleShips; + static void init() throws IOException { + int commandCount = Integer.parseInt(br.readLine().trim()); + int time = 0; + while(commandCount-- > 0) { + st = new StringTokenizer(br.readLine().trim()); + int command = Integer.parseInt(st.nextToken()); + switch(command) { + case 100: { + /** + * [공격 준비] + * N척의 선박에 사격 준비 지시 + * 선발 (id, 공격력, 재장전 시간, 상태 - 초기 상태는 사격 대기) + */ + readyAttack(); + break; + } + case 200: { + /** + * [지원 요청] + * 새로운 선박 합류 + */ + addNewBattleShip(); + break; + } + case 300: { + /** + * [함포 교체] + * id번 선박의 함포를 교체한다. (공격력 변경) + */ + changeCanon(); + break; + } + case 400: { + /** + * [공격 명령] + * 사격 대기 상태인 선박 중 공격력이 가장 높은 5척이 공격한다. + * - 공격력이 같다면 id가 낮은 것이 우선순위를 갖는다. + * - 사격 후 즉시 재장전에 들어간다. -> 사격 시점을 포함해 r 시간이 경과하면 사격 대기 상태로 변한다. + * + * => 총 피해량, 사격에 참여한 선박 수, 우선순위 id + */ + sb.append(attack(time)).append('\n'); + break; + } + } + /** + * 재장전 시간 감소 + */ + time++; + while(!waitBattleShips.isEmpty() && waitBattleShips.peek().remainShoot <= time) { + BattleShip battleShip = waitBattleShips.poll(); + readyBattleShips.add(battleShip); + } + } + } + static class BattleShip { + int id; + int pw; + int reload; + int remainShoot; + + BattleShip(int id, int pw, int reload) { + this.id = id; + this.pw = pw; + this.reload = reload; + + this.remainShoot = 0; // 초기에는 무조건 쏠 수 있도록 최소 값 + } + + int shoot(int time) { + this.remainShoot = this.reload + time; + return this.pw; + } + } + /** + * [공격 준비] + */ + static void readyAttack() { + bindBattleShips = new HashMap<>(); + waitBattleShips = new PriorityQueue<>((a, b) -> Integer.compare(a.remainShoot, b.remainShoot)); + readyBattleShips = new TreeSet<>((a, b) -> { + if(a.pw != b.pw) return Integer.compare(b.pw, a.pw); // 2. 공격력이 쎈 함선이 우선 + return Integer.compare(a.id, b.id); // id 가 작은 함선이 우선 + }); + + int battleShipCount = Integer.parseInt(st.nextToken()); + while(battleShipCount-- > 0) { + int id = Integer.parseInt(st.nextToken()); + int pw = Integer.parseInt(st.nextToken()); + int reload = Integer.parseInt(st.nextToken()); + BattleShip battleShip = new BattleShip(id, pw, reload); + readyBattleShips.add(battleShip); + bindBattleShips.put(id, battleShip); + } + } + /** + * [지원 요청] + */ + static void addNewBattleShip() { + int id = Integer.parseInt(st.nextToken()); + int pw = Integer.parseInt(st.nextToken()); + int reload = Integer.parseInt(st.nextToken()); + BattleShip battleShip = new BattleShip(id, pw, reload); + readyBattleShips.add(battleShip); + bindBattleShips.put(id, battleShip); + } + /** + * [함포 교체] + */ + static void changeCanon() { + int id = Integer.parseInt(st.nextToken()); + int pw = Integer.parseInt(st.nextToken()); + + BattleShip battleShip = bindBattleShips.get(id); + if(readyBattleShips.remove(battleShip)) { + battleShip.pw = pw; + readyBattleShips.add(battleShip); + } else { + battleShip.pw = pw; + } + } + /** + * [공격 명령] + */ + static String attack(int time) { + List shootList = new ArrayList<>(); + + for(BattleShip battleShip : readyBattleShips) { + shootList.add(battleShip); + if(shootList.size() == 5) break; // 최대 5개의 함선만 사격 + } + + // 업데이트 + StringBuilder shootSb = new StringBuilder(); + shootSb.append(' ').append(shootList.size()).append(' '); + int totalPw = 0; + for(BattleShip battleShip : shootList) { + readyBattleShips.remove(battleShip); + totalPw += battleShip.shoot(time); + shootSb.append(battleShip.id).append(' '); + waitBattleShips.add(battleShip); + } + shootSb.insert(0, totalPw); + return shootSb.toString(); + } +} diff --git "a/java/src/feb/week1/swea/\353\257\270\354\203\235\353\254\274\352\262\251\353\246\254_\353\260\225\354\236\254\355\231\230.java" "b/java/src/feb/week1/swea/\353\257\270\354\203\235\353\254\274\352\262\251\353\246\254_\353\260\225\354\236\254\355\231\230.java" new file mode 100644 index 0000000..8e7ae6f --- /dev/null +++ "b/java/src/feb/week1/swea/\353\257\270\354\203\235\353\254\274\352\262\251\353\246\254_\353\260\225\354\236\254\355\231\230.java" @@ -0,0 +1,131 @@ +package feb.week1.swea; + +import java.util.*; +import java.io.*; + +public class 미생물격리_박재환 { + static BufferedReader br; + static StringBuilder sb; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + sb = new StringBuilder(); + int tc = Integer.parseInt(br.readLine().trim()); + for(int i=1; i 0) { + Map> afterMove = new HashMap<>(); + /** + * [군집 이동] + */ + for(int i=0; i new ArrayList<>()).add(group); + } + /** + * [약품이 칠해져있는 구역 확인] + */ + for(Group group : groups) { + if(!group.isLive) continue; + if(isBoundary(group.x, group.y)) { + group.size /= 2; + group.turn(); + } + } + /** + * [합쳐지는 군집 처리] + */ + for(Map.Entry> entry : afterMove.entrySet()) { + List list = entry.getValue(); + if(list.size() < 2) continue; // 충돌하지 않은 군집 + // 충돌한 군집 + list.sort((a, b) -> Integer.compare(b.size, a.size)); + int sum = 0; + for(int i=1; i Date: Thu, 5 Feb 2026 10:39:42 +0900 Subject: [PATCH 12/20] =?UTF-8?q?BOJ=2012100=202048(Easy)=20=ED=92=80?= =?UTF-8?q?=EC=9D=B4(=EA=B5=AC=ED=98=84)=20-=20=EB=B0=95=EC=9E=AC=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\353\260\225\354\236\254\355\231\230.java" | 194 ++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 "java/src/feb/week1/boj/easy2048_\353\260\225\354\236\254\355\231\230.java" diff --git "a/java/src/feb/week1/boj/easy2048_\353\260\225\354\236\254\355\231\230.java" "b/java/src/feb/week1/boj/easy2048_\353\260\225\354\236\254\355\231\230.java" new file mode 100644 index 0000000..7a0074d --- /dev/null +++ "b/java/src/feb/week1/boj/easy2048_\353\260\225\354\236\254\355\231\230.java" @@ -0,0 +1,194 @@ +package feb.week1.boj; + +import java.util.*; +import java.io.*; + +public class easy2048_박재환 { + static BufferedReader br; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + init(); + br.close(); + } + static StringTokenizer st; + static int n; + static void init() throws IOException { + n = Integer.parseInt(br.readLine().trim()); + Block[][] map = new Block[n][n]; + for(int x=0; x q = new ArrayDeque<>(); + for(int x=0; x q = new ArrayDeque<>(); + for(int x=0; x-1; y--) { + if(map[x][y] == null) continue; + // 빈칸이 아닐 때 + if(!q.isEmpty() && !q.getLast().increase && q.getLast().num == map[x][y].num) { + q.getLast().increase = true; + } else { + q.offer(map[x][y]); + } + } + for(int y=n-1; y>-1; y--) { + if(!q.isEmpty()) { + Block block = q.poll(); + if(block.increase) block.num *= 2; + map[x][y] = block; + } else { + map[x][y] = null; + } + } + } + } + static void top(Block[][] map) { + Deque q = new ArrayDeque<>(); + for(int y=0; y q = new ArrayDeque<>(); + for(int y=0; y-1; x--) { + if(map[x][y] == null) continue; + // 빈칸이 아닐 때 + if(!q.isEmpty() && !q.getLast().increase && q.getLast().num == map[x][y].num) { + q.getLast().increase = true; + } else { + q.offer(map[x][y]); + } + } + for(int x=n-1; x>-1; x--) { + if(!q.isEmpty()) { + Block block = q.poll(); + if(block.increase) block.num *= 2; + map[x][y] = block; + } else { + map[x][y] = null; + } + } + } + } + static Block[][] copyMap(Block[][] map) { + Block[][] copy = new Block[n][n]; + for(int x=0; x Date: Thu, 5 Feb 2026 17:14:30 +0900 Subject: [PATCH 13/20] =?UTF-8?q?CODETREE=20AI=EB=A1=9C=EB=B4=87=EC=B2=AD?= =?UTF-8?q?=EC=86=8C=EA=B8=B0=20=ED=92=80=EC=9D=B4(=EA=B5=AC=ED=98=84)=20-?= =?UTF-8?q?=20=EB=B0=95=EC=9E=AC=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\353\260\225\354\236\254\355\231\230.java" | 270 ++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 "java/src/feb/week1/codetree/AI\353\241\234\353\264\207\354\262\255\354\206\214\352\270\260_\353\260\225\354\236\254\355\231\230.java" diff --git "a/java/src/feb/week1/codetree/AI\353\241\234\353\264\207\354\262\255\354\206\214\352\270\260_\353\260\225\354\236\254\355\231\230.java" "b/java/src/feb/week1/codetree/AI\353\241\234\353\264\207\354\262\255\354\206\214\352\270\260_\353\260\225\354\236\254\355\231\230.java" new file mode 100644 index 0000000..25d5463 --- /dev/null +++ "b/java/src/feb/week1/codetree/AI\353\241\234\353\264\207\354\262\255\354\206\214\352\270\260_\353\260\225\354\236\254\355\231\230.java" @@ -0,0 +1,270 @@ +package feb.week1.codetree; + +import java.util.*; +import java.io.*; + +public class AI로봇청소기_박재환 { + static BufferedReader br; + static StringBuilder sb; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + sb = new StringBuilder(); + init(); + br.close(); + System.out.println(sb); + } + /** + * N x N + * - 먼지 O + * - 먼지 X + * - 물건 + * + * 먼지가 있는 공간은 1~100사이의 먼지 양을 갖는다. + * + * [청소기 이동] + * 이동거리가 가장 가까운 오염된 격자로 이동한다. (청소기 순서대로, 동시 X) + * 물건 혹은 청소기가 있는 격자로 지나갈 수 없다. + * 가까운 격자가 여러 개, (행 번호 작은 것 -> 열 번호 작은 것) + * + * [청소] + * 바라보고 있는 방향 기준, 본인이 위치한 격자, 왼쪽, 오른쪽, 위쪽 을 청소할 수 있다. + * 4가지 방향 중 가장 큰 방향에서 청소를 시작한다. + * 격자별 최대 청소 가능 20 + * 합이 여러개 (오른쪽 > 아래 > 왼쪽 > 위쪽) + * + * [먼지축적] + * 먼지가 있는 모든 격자에 동시에 5씩 추가된다 + * + * [먼지확산] + * 깨끗한 격자에 주변 4방향 격자의 먼지량 합을 10으로 나눈 값만큼 먼지가 확산 + * 편의상 나눗셈 과정에 생기는 소숫점 아래 수는 버린다. + * 모든 깨끗한 격자에 대해 동시에 확산이 이루어진다. + * + * [출력] + * 전체 공간의 총 먼지량을 출력한다. + * 먼지가 있는 곳이 없으면 0을 출력한다. + */ + static StringTokenizer st; + static int n, k, l; + static int[][] board; + static Robot[] robots; + static boolean[][] isAllocated; + static void init() throws IOException { + st = new StringTokenizer(br.readLine().trim()); + n = Integer.parseInt(st.nextToken()); // 격자 크기 + k = Integer.parseInt(st.nextToken()); // 로봇 청소기 개수 + l = Integer.parseInt(st.nextToken()); // 테스트 횟수 + board = new int[n][n]; + for(int x=0; x 0) { + /** + * [청소기이동] + */ + moveRobots(); + /** + * [청소] + */ + clean(); + /** + * [먼지축적] + */ + accDust(); + /** + * [먼지확산] + */ + spreadDust(); + /** + * [출력] + */ + printDust(); + } + } + static void printDust() { + int sum = 0; + for(int x=0; x 먼지량의 합이 가장 큰 방향에서 청소를 시작한다. + * 오른쪽 -> 아래쪽 -> 왼쪽 -> 위쪽 + */ + for(Robot robot : robots) { + // 현재 로봇이 청소할 방향을 결정 + int dir = decisionCleanDir(robot); + if(dir == -1) continue; + doClean(robot.x, robot.y, dir); + } + } + static void doClean(int x, int y, int dir) { + board[x][y] = Math.max(board[x][y]-20, 0); + // 위 + int nx = x + dx[dir]; + int ny = y + dy[dir]; + if(!isNotBoard(nx, ny) && board[nx][ny] > 0) board[nx][ny] = Math.max(board[nx][ny]-20, 0); + // 왼쪽 + nx = x + dx[(dir-1+4)%4]; + ny = y + dy[(dir-1+4)%4]; + if(!isNotBoard(nx, ny) && board[nx][ny] > 0) board[nx][ny] = Math.max(board[nx][ny]-20, 0); + // 오른쪽 + nx = x + dx[(dir+1)%4]; + ny = y + dy[(dir+1)%4]; + if(!isNotBoard(nx, ny) && board[nx][ny] > 0) board[nx][ny] = Math.max(board[nx][ny]-20, 0); + } + static int decisionCleanDir(Robot robot) { + int maxSum, maxDir; + maxSum = 0; + maxDir = -1; + for(int id=0; id<4; id++) { + int dir = prioritySearchDir[id]; + int sum = getSum(robot.x, robot.y, dir); + + if(maxSum < sum) { + maxSum = sum; + maxDir = dir; + } + } + return maxDir; + } + static int getSum(int x, int y, int dir) { + int sum = Math.min(board[x][y], 20); + // 위 (앞) + int nx = x + dx[dir]; + int ny = y + dy[dir]; + if(!isNotBoard(nx, ny) && board[nx][ny] > 0) sum += Math.min(board[nx][ny], 20); + // 왼쪽 + nx = x + dx[(dir-1+4)%4]; + ny = y + dy[(dir-1+4)%4]; + if(!isNotBoard(nx, ny) && board[nx][ny] > 0) sum += Math.min(board[nx][ny], 20); + // 오른쪽 + nx = x + dx[(dir+1)%4]; + ny = y + dy[(dir+1)%4]; + if(!isNotBoard(nx, ny) && board[nx][ny] > 0) sum += Math.min(board[nx][ny], 20); + return sum; + } + static boolean isNotBoard(int x, int y) { + return x < 0 || y < 0 || x >= n || y >= n; + } + static void moveRobots() { + /** + * 순서대로 청소기를 움직인다. + */ + for(int robotId=0; robotId 0) continue; + int[] newLocation = findNearLocation(robotId); + if(newLocation == null) continue; + isAllocated[robot.x][robot.y] = false; + robot.updateLocation(newLocation); + isAllocated[robot.x][robot.y] = true; + } + } + static int[] findNearLocation(int robotId) { + Queue q = new ArrayDeque<>(); + boolean[][] visited = new boolean[n][n]; + + Robot robot = robots[robotId]; + q.offer(new int[] {robot.x, robot.y, 0}); + visited[robot.x][robot.y] = true; + + int bestX, bestY, bestDist; + bestX = bestY = n; + bestDist = n*n+5; + while(!q.isEmpty()) { + int[] cur = q.poll(); + int x = cur[0]; + int y = cur[1]; + int dist = cur[2]; + if(bestDist < dist) break; + for(int dir=0; dir<4; dir++) { + int nx = x+dx[dir]; + int ny = y+dy[dir]; + if(isNotBoard(nx, ny)) continue; + if(visited[nx][ny] || isAllocated[nx][ny] || board[nx][ny] == -1) continue; + visited[nx][ny] = true; + q.offer(new int[] {nx, ny, dist+1}); + if(board[nx][ny] > 0) { // 먼지가 있는 칸이라면 + if(bestDist > dist + 1) { + bestX = nx; + bestY = ny; + bestDist = dist + 1; + } else if(bestDist == dist + 1) { + if(bestX > nx || (bestX == nx && bestY > ny)) { + bestX = nx; + bestY = ny; + } + } + } + } + } + if(bestX == n && bestY == n) return null; + return new int[] {bestX, bestY}; + } +} From d0d1ef26db589ff141bb2cf26ade1b3d4f160169 Mon Sep 17 00:00:00 2001 From: Hwannee00 Date: Thu, 5 Feb 2026 18:41:05 +0900 Subject: [PATCH 14/20] =?UTF-8?q?SWEA=20=ED=99=88=20=EB=B0=A9=EB=B2=94=20?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=20=ED=92=80=EC=9D=B4=20-=20?= =?UTF-8?q?=EB=B0=95=EC=9E=AC=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\353\260\225\354\236\254\355\231\230.java" | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 "java/src/feb/week1/swea/\355\231\210\353\260\251\353\262\224\354\204\234\353\271\204\354\212\244_\353\260\225\354\236\254\355\231\230.java" diff --git "a/java/src/feb/week1/swea/\355\231\210\353\260\251\353\262\224\354\204\234\353\271\204\354\212\244_\353\260\225\354\236\254\355\231\230.java" "b/java/src/feb/week1/swea/\355\231\210\353\260\251\353\262\224\354\204\234\353\271\204\354\212\244_\353\260\225\354\236\254\355\231\230.java" new file mode 100644 index 0000000..1fdd61d --- /dev/null +++ "b/java/src/feb/week1/swea/\355\231\210\353\260\251\353\262\224\354\204\234\353\271\204\354\212\244_\353\260\225\354\236\254\355\231\230.java" @@ -0,0 +1,71 @@ +package feb.week1.swea; + +import java.util.*; +import java.io.*; + +public class 홈방범서비스_박재환 { + static BufferedReader br; + static StringBuilder sb; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + sb = new StringBuilder(); + int tc = Integer.parseInt(br.readLine().trim()); + for(int i=1; i Date: Fri, 6 Feb 2026 11:28:39 +0900 Subject: [PATCH 15/20] =?UTF-8?q?BOJ=202835=20=EC=9D=B8=EA=B8=B0=EB=8F=84?= =?UTF-8?q?=20=EC=A1=B0=EC=82=AC=20=ED=92=80=EC=9D=B4(=EB=88=84=EC=A0=81?= =?UTF-8?q?=ED=95=A9)=20-=20=EB=B0=95=EC=9E=AC=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\353\260\225\354\236\254\355\231\230.java" | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 "java/src/feb/week1/boj/\354\235\270\352\270\260\353\217\204\354\241\260\354\202\254_\353\260\225\354\236\254\355\231\230.java" diff --git "a/java/src/feb/week1/boj/\354\235\270\352\270\260\353\217\204\354\241\260\354\202\254_\353\260\225\354\236\254\355\231\230.java" "b/java/src/feb/week1/boj/\354\235\270\352\270\260\353\217\204\354\241\260\354\202\254_\353\260\225\354\236\254\355\231\230.java" new file mode 100644 index 0000000..a130bba --- /dev/null +++ "b/java/src/feb/week1/boj/\354\235\270\352\270\260\353\217\204\354\241\260\354\202\254_\353\260\225\354\236\254\355\231\230.java" @@ -0,0 +1,74 @@ +package feb.week1.boj; + +import java.util.*; +import java.io.*; + +public class 인기도조사_박재환 { + static BufferedReader br; + static StringBuilder sb; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + sb = new StringBuilder(); + init(); + br.close(); + System.out.println(sb); + } + static final int SECOND = 1; + static final int MINUTE = 60; + static final int HOUR = 60*60; + /** + * 티비를 시청한 구간 + * HH:MM:SS - HH:MM:SS + */ + static StringTokenizer st; + static long[] timeStamp; + static long[] prefix; + static void init() throws IOException { + timeStamp = new long[HOUR*24+1]; + int inputCount = Integer.parseInt(br.readLine().trim()); + while(inputCount-- > 0) { + st = new StringTokenizer(br.readLine().trim(), " :-"); + int s = convertToSecond(); + int e = convertToSecond(); + if (s <= e) { + timeStamp[s]++; + timeStamp[e + 1]--; + } else { + // 자정 넘김 + timeStamp[s]++; + timeStamp[HOUR*24]--; + timeStamp[0]++; + timeStamp[e + 1]--; + } + } + + for(int i=1; i 0) { + st = new StringTokenizer(br.readLine().trim(), " :-"); + int s = convertToSecond(); + int e = convertToSecond(); + long sum; + int len; + + if (s <= e) { + sum = prefix[e + 1] - prefix[s]; + len = e - s + 1; + } else { + sum = (prefix[HOUR*24] - prefix[s]) + prefix[e + 1]; + len = (HOUR*24 - s) + (e + 1); + } + + sb.append(String.format("%.10f", (double) sum / len)).append('\n'); + } + } + static int convertToSecond() { + int h = Integer.parseInt(st.nextToken()) * HOUR; + int m = Integer.parseInt(st.nextToken()) * MINUTE; + int s = Integer.parseInt(st.nextToken()) * SECOND; + return h+m+s; + } +} From 27de7bdd89e15fe880dc5237b08797a3e7a543a9 Mon Sep 17 00:00:00 2001 From: Hwannee00 Date: Fri, 6 Feb 2026 11:28:51 +0900 Subject: [PATCH 16/20] =?UTF-8?q?BOJ=202835=20=EC=9D=B8=EA=B8=B0=EB=8F=84?= =?UTF-8?q?=20=EC=A1=B0=EC=82=AC=20=ED=92=80=EC=9D=B4(LAZY=20SegmentTree)?= =?UTF-8?q?=20-=20=EB=B0=95=EC=9E=AC=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\353\260\225\354\236\254\355\231\230.java" | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 "java/src/feb/week1/boj/\354\235\270\352\270\260\353\217\204\354\241\260\354\202\254_\354\204\270\352\267\270\353\250\274\355\212\270\355\212\270\353\246\254_\353\260\225\354\236\254\355\231\230.java" diff --git "a/java/src/feb/week1/boj/\354\235\270\352\270\260\353\217\204\354\241\260\354\202\254_\354\204\270\352\267\270\353\250\274\355\212\270\355\212\270\353\246\254_\353\260\225\354\236\254\355\231\230.java" "b/java/src/feb/week1/boj/\354\235\270\352\270\260\353\217\204\354\241\260\354\202\254_\354\204\270\352\267\270\353\250\274\355\212\270\355\212\270\353\246\254_\353\260\225\354\236\254\355\231\230.java" new file mode 100644 index 0000000..9aa65ea --- /dev/null +++ "b/java/src/feb/week1/boj/\354\235\270\352\270\260\353\217\204\354\241\260\354\202\254_\354\204\270\352\267\270\353\250\274\355\212\270\355\212\270\353\246\254_\353\260\225\354\236\254\355\231\230.java" @@ -0,0 +1,106 @@ +package feb.week1.boj; + +import java.util.*; +import java.io.*; + +public class 인기도조사_세그먼트트리_박재환 { + static BufferedReader br; + static StringBuilder sb; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + sb = new StringBuilder(); + init(); + br.close(); + System.out.println(sb); + } + static final int SECOND = 1; + static final int MINUTE = 60 * SECOND; + static final int HOUR = 60 * MINUTE; + static final int DAY = 24 * HOUR; + + static long[] tree; + static long[] lazy; + + static StringTokenizer st; + static void init() throws IOException { + tree = new long[DAY * 4]; // 세그먼트 트리 + lazy = new long[DAY * 4]; // 지연 기록 + + int inputCount = Integer.parseInt(br.readLine().trim()); + while (inputCount-- > 0) { + st = new StringTokenizer(br.readLine(), " :-"); + int s = convertToSecond(); + int e = convertToSecond(); + + if (s <= e) { + update(1, 0, DAY - 1, s, e, 1); + } else { // 자정을 넘기는 경우 + update(1, 0, DAY - 1, s, DAY - 1, 1); + update(1, 0, DAY - 1, 0, e, 1); + } + } + int outputCount = Integer.parseInt(br.readLine().trim()); + while (outputCount-- > 0) { + st = new StringTokenizer(br.readLine(), " :-"); + int s = convertToSecond(); + int e = convertToSecond(); + + long sum; + int len; + + if (s <= e) { + sum = query(1, 0, DAY - 1, s, e); + len = e - s + 1; + } else { // 자정을 넘기는 경우 + sum = query(1, 0, DAY - 1, s, DAY - 1) + + query(1, 0, DAY - 1, 0, e); + len = (DAY - s) + (e + 1); // DAY-1 - s + 1 => DAY - s, e - 0 + 1 => e + 1 + } + sb.append(String.format("%.10f", (double) sum / len)).append('\n'); + } + } + static void update(int id, int l, int r, int s, int e, long targetValue) { + if(r < s || l > e) return; // 범위 벗어남 + if(l >= s && r <= e) { // 완전하게 포함 + // LAZY 기록 후 종료 + tree[id] += targetValue * (r-l+1); // 자식의 개수만큼 증가 + lazy[id] += targetValue; // 자식에게 넘길 값 + return; + } + // 일부만 포함 -> LAZY 전파 후 이어서 탐색 + push(id, l, r); + int mid = l + (r-l)/2; + update(id*2, l, mid, s, e, targetValue); + update(id*2+1, mid+1, r, s, e, targetValue); + tree[id] = tree[id*2] + tree[id*2+1]; + } + static long query(int id, int l, int r, int s, int e) { + if(r < s || l > e) return 0L; // 범위 벗어남 + if(l >= s && r <= e) return tree[id]; // 완전하게 포함 + + push(id, l, r); + int mid = l + (r-l)/2; + return query(id*2, l, mid, s, e) + query(id*2+1, mid+1, r, s, e); + } + static void push(int id, int l, int r) { + if(lazy[id] == 0 || l == r) return; // 전파할 값이 없거나, 리프노드인 경우 + int mid = l + (r-l)/2; + long lazyValue = lazy[id]; + + // 왼쪽 자식 전파 + tree[id*2] += lazyValue * (mid-l+1); + lazy[id*2] += lazyValue; + // 오른쪽 자식 전파 + tree[id*2+1] += lazyValue * (r-mid); // r - (mid+1) + 1 => r - mid + lazy[id*2+1] += lazyValue; + + // 전파 완료 + lazy[id] = 0; + } + static int convertToSecond() { + int h = Integer.parseInt(st.nextToken()) * HOUR; + int m = Integer.parseInt(st.nextToken()) * MINUTE; + int s = Integer.parseInt(st.nextToken()) * SECOND; + return h+m+s; + } +} From 338f026c7521820645f38987816d633d9bb5bc0f Mon Sep 17 00:00:00 2001 From: Hwannee00 Date: Fri, 6 Feb 2026 12:18:35 +0900 Subject: [PATCH 17/20] =?UTF-8?q?BOJ=201113=20=EC=88=98=EC=98=81=EC=9E=A5?= =?UTF-8?q?=20=EB=A7=8C=EB=93=A4=EA=B8=B0=20=ED=92=80=EC=9D=B4(BFS)=20-=20?= =?UTF-8?q?=EB=B0=95=EC=9E=AC=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\353\260\225\354\236\254\355\231\230.java" | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 "java/src/feb/week1/boj/\354\210\230\354\230\201\354\236\245\353\247\214\353\223\244\352\270\260_\353\260\225\354\236\254\355\231\230.java" diff --git "a/java/src/feb/week1/boj/\354\210\230\354\230\201\354\236\245\353\247\214\353\223\244\352\270\260_\353\260\225\354\236\254\355\231\230.java" "b/java/src/feb/week1/boj/\354\210\230\354\230\201\354\236\245\353\247\214\353\223\244\352\270\260_\353\260\225\354\236\254\355\231\230.java" new file mode 100644 index 0000000..d6e3710 --- /dev/null +++ "b/java/src/feb/week1/boj/\354\210\230\354\230\201\354\236\245\353\247\214\353\223\244\352\270\260_\353\260\225\354\236\254\355\231\230.java" @@ -0,0 +1,95 @@ +package feb.week1.boj; + +import java.util.*; +import java.io.*; + +public class 수영장만들기_박재환 { + /** + * 바깥으로 물이 세지 않는 칸들에, 주변 벽보다 낮은 만큼 물이 고인다. + * + * 갇혀있는 영역을 찾는다. => BFS / DFS + */ + static BufferedReader br; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + init(); + br.close(); + } + static StringTokenizer st; + static int n, m; + static int[][] map; + static void init() throws IOException { + st = new StringTokenizer(br.readLine().trim()); + n = Integer.parseInt(st.nextToken()); + m = Integer.parseInt(st.nextToken()); + map = new int[n][m]; + for(int x=0; x 물의 높이 1 ~ 8 + */ + int result = 0; + for(int height=2; height<10; height++) { + result += checkWaterHeight(height); + } + return result; + } + static int[] dx = {0,1,0,-1}; + static int[] dy = {1,0,-1,0}; + static int checkWaterHeight(int height) { + /** + * 물이 채워질 수 없는 칸을 체크한다. + */ + Queue q = new ArrayDeque<>(); + boolean[][] visited = new boolean[n][m]; + + // 시작 후보지점 정하기 + // 경계이거나, 물 높이보다 낮은 칸 + // => 물이 흘러나갈 수 있는 칸의 후보 + for(int x=0; x= n || ny >= m) continue; + if(visited[nx][ny] || map[nx][ny] >= height) continue; + + visited[nx][ny] = true; + q.offer(new int[] {nx, ny}); + } + } + + int water = 0; + for (int x = 0; x < n; x++) { + for (int y = 0; y < m; y++) { + if (map[x][y] < height && !visited[x][y]) { + water++; + } + } + } + return water; + } +} From 14621d3ff612a7d309e6a2cd0504d2ea6da785b3 Mon Sep 17 00:00:00 2001 From: Hwannee00 Date: Fri, 6 Feb 2026 12:40:28 +0900 Subject: [PATCH 18/20] =?UTF-8?q?BOJ=201113=20=EC=88=98=EC=98=81=EC=9E=A5?= =?UTF-8?q?=20=EB=A7=8C=EB=93=A4=EA=B8=B0=20=ED=92=80=EC=9D=B4(BFS)=20-=20?= =?UTF-8?q?=EB=B0=95=EC=9E=AC=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0_\353\260\225\354\236\254\355\231\230.py" | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 "python/src/feb/week1/boj/\354\210\230\354\230\201\354\236\245\353\247\214\353\223\244\352\270\260_\353\260\225\354\236\254\355\231\230.py" diff --git "a/python/src/feb/week1/boj/\354\210\230\354\230\201\354\236\245\353\247\214\353\223\244\352\270\260_\353\260\225\354\236\254\355\231\230.py" "b/python/src/feb/week1/boj/\354\210\230\354\230\201\354\236\245\353\247\214\353\223\244\352\270\260_\353\260\225\354\236\254\355\231\230.py" new file mode 100644 index 0000000..20e9bae --- /dev/null +++ "b/python/src/feb/week1/boj/\354\210\230\354\230\201\354\236\245\353\247\214\353\223\244\352\270\260_\353\260\225\354\236\254\355\231\230.py" @@ -0,0 +1,53 @@ +def solution(): + import sys + input = sys.stdin.readline + + n,m = map(int, input().split()) + board = [list(map(int, input().strip())) for _ in range(n)] + + dx = [1,0,-1,0] + dy = [0,1,0,-1] + def check_water_h(h): + from collections import deque + q = deque() + visited = [[False] * m for _ in range(n)] + + # 경계부터 탐색하며, 물이 찰 수 없는 위치를 시작 포인트로 기록 + for x in range(n): + for y in range(m): + if x == 0 or y == 0 or x == n-1 or y == m-1: + if board[x][y] < h: + visited[x][y] = True + q.append((x, y)) + + while q: + x, y = q.popleft() + + for dir in range(4): + nx = x + dx[dir] + ny = y + dy[dir] + + if nx < 0 or ny < 0 or nx >= n or ny >=m: + continue + if visited[nx][ny] or board[nx][ny] >= h: + continue + + visited[nx][ny] = True + q.append((nx, ny)) + + water = 0 + for x in range(n): + for y in range(m): + if not visited[x][y] and board[x][y] < h: + water+=1 + return water + + result = 0 + for h in range(2,10): + result += check_water_h(h) + + return result + +if __name__ == '__main__': + print(solution()) + From 603c796f8009dd47ec68514c4c76b05a13103707 Mon Sep 17 00:00:00 2001 From: Hwannee00 Date: Fri, 6 Feb 2026 15:55:42 +0900 Subject: [PATCH 19/20] =?UTF-8?q?BOJ=2016975=20=EC=88=98=EC=97=B4=EA=B3=BC?= =?UTF-8?q?=20=EC=BF=BC=EB=A6=AC21=20=ED=92=80=EC=9D=B4(Lazy=20SegmentTree?= =?UTF-8?q?)=20-=20=EB=B0=95=EC=9E=AC=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\353\260\225\354\236\254\355\231\230.java" | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 "java/src/feb/week1/boj/\354\210\230\354\227\264\352\263\274\354\277\274\353\246\25421_\353\260\225\354\236\254\355\231\230.java" diff --git "a/java/src/feb/week1/boj/\354\210\230\354\227\264\352\263\274\354\277\274\353\246\25421_\353\260\225\354\236\254\355\231\230.java" "b/java/src/feb/week1/boj/\354\210\230\354\227\264\352\263\274\354\277\274\353\246\25421_\353\260\225\354\236\254\355\231\230.java" new file mode 100644 index 0000000..25a8f0a --- /dev/null +++ "b/java/src/feb/week1/boj/\354\210\230\354\227\264\352\263\274\354\277\274\353\246\25421_\353\260\225\354\236\254\355\231\230.java" @@ -0,0 +1,85 @@ +package feb.week1.boj; + +import java.util.*; +import java.io.*; + +public class 수열과쿼리21_박재환 { + static BufferedReader br; + static StringBuilder sb; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + sb = new StringBuilder(); + init(); + br.close(); + System.out.println(sb); + } + static StringTokenizer st; + static int n; + static int[] arr; + static long[] tree; + static long[] lazy; + static void init() throws IOException { + n = Integer.parseInt(br.readLine().trim()); + arr = new int[n]; + tree = new long[4*n]; + lazy = new long[4*n]; + st = new StringTokenizer(br.readLine().trim()); + for(int i=0; i 0) { + st = new StringTokenizer(br.readLine().trim()); + int command = Integer.parseInt(st.nextToken()); + switch(command) { + case 1: { // 구간 변경 + int s = Integer.parseInt(st.nextToken())-1; + int e = Integer.parseInt(st.nextToken())-1; + int v = Integer.parseInt(st.nextToken()); + update(1, 0, n-1, s, e, v); + break; + } + case 2: { // 구간 출력 + int targetId = Integer.parseInt(st.nextToken())-1; + sb.append(query(1, 0, n-1, targetId, targetId)).append('\n'); + break; + } + } + } + } + static long initTree(int id, int l, int r) { + if(l == r) return tree[id] = arr[l]; + int mid = l + (r-l)/2; + return tree[id] = initTree(id*2, l, mid) + initTree(id*2+1, mid+1, r); + } + static void update(int id, int l, int r, int s, int e, long v) { + if(r < s || l > e) return; + if(l >= s && r <= e) { // 완전하게 포함 + tree[id] += (v * (r-l+1)); + lazy[id] += v; + return; + } + // 부분 포함 + push(id, l, r); + int mid = l + (r-l)/2; + update(id*2, l, mid, s, e, v); + update(id*2+1, mid+1, r, s, e, v); + tree[id] = tree[id*2] + tree[id*2+1]; + } + static long query(int id, int l, int r, int s, int e) { + if(r < s || l > e) return 0; + if(l >= s && r <= e) return tree[id]; + push(id, l, r); + int mid = l + (r-l)/2; + return query(id*2, l, mid, s, e) + query(id*2+1, mid+1, r, s, e); + } + static void push(int id, int l, int r) { + if(lazy[id] == 0 || l == r) return; + long v = lazy[id]; + int mid = l + (r-l)/2; + tree[id*2] += v * (mid-l+1); + lazy[id*2] += v; + tree[id*2+1] += v * (r-mid); + lazy[id*2+1] += v; + lazy[id] = 0; + } +} From 6785706dd122b5a9c394a9e7c3cce1e981a1fd7b Mon Sep 17 00:00:00 2001 From: Park Jae Hwan Date: Sat, 7 Feb 2026 09:21:37 +0900 Subject: [PATCH 20/20] =?UTF-8?q?BOJ=201507=20=EA=B6=81=EA=B8=88=ED=95=9C?= =?UTF-8?q?=20=EB=AF=BC=ED=98=B8=20=ED=92=80=EC=9D=B4(=ED=94=8C=EB=A1=9C?= =?UTF-8?q?=EC=9D=B4=EB=93=9C=EC=9B=8C=EC=83=AC)=20-=20=EB=B0=95=EC=9E=AC?= =?UTF-8?q?=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\353\260\225\354\236\254\355\231\230.java" | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 "java/src/feb/week1/boj/\352\266\201\352\270\210\355\225\234\353\257\274\355\230\270_\353\260\225\354\236\254\355\231\230.java" diff --git "a/java/src/feb/week1/boj/\352\266\201\352\270\210\355\225\234\353\257\274\355\230\270_\353\260\225\354\236\254\355\231\230.java" "b/java/src/feb/week1/boj/\352\266\201\352\270\210\355\225\234\353\257\274\355\230\270_\353\260\225\354\236\254\355\231\230.java" new file mode 100644 index 0000000..fe69431 --- /dev/null +++ "b/java/src/feb/week1/boj/\352\266\201\352\270\210\355\225\234\353\257\274\355\230\270_\353\260\225\354\236\254\355\231\230.java" @@ -0,0 +1,55 @@ +package feb.week1.boj; + +import java.util.*; +import java.io.*; + +public class 궁금한민호_박재환 { + static BufferedReader br; + public static void main(String[] args) throws IOException { + br = new BufferedReader(new InputStreamReader(System.in)); + init(); + br.close(); + } + static StringTokenizer st; + static int n; + static int[][] map; + static void init() throws IOException { + n = Integer.parseInt(br.readLine().trim()); + map = new int[n][n]; + /** + * 주어지는 경로는 이미 최소거리 + */ + for(int from=0; from map[from][mid] + map[mid][to]) return -1; // 최소 경로가 아니였을 때 + else if(map[from][to] == map[from][mid] + map[mid][to]) { // 동일한 비용의 경로가 존재한다면 -> 도로의 개수가 최소가 되어야하므로, 경유 도로 제거 + unUsed[from][to] = true; + } + } + } + } + int sum = 0; + for(int from=0; from