diff --git "a/.github/ISSUE_TEMPLATE/sql-\355\222\200\354\235\264-\353\252\250\354\235\214-\355\205\234\355\224\214\353\246\277.md" "b/.github/ISSUE_TEMPLATE/sql-\355\222\200\354\235\264-\353\252\250\354\235\214-\355\205\234\355\224\214\353\246\277.md" index b1b2d64a..9167d0c7 100644 --- "a/.github/ISSUE_TEMPLATE/sql-\355\222\200\354\235\264-\353\252\250\354\235\214-\355\205\234\355\224\214\353\246\277.md" +++ "b/.github/ISSUE_TEMPLATE/sql-\355\222\200\354\235\264-\353\252\250\354\235\214-\355\205\234\355\224\214\353\246\277.md" @@ -16,12 +16,13 @@ assignees: '' 백제완: []() -이지영: +손지민: []() -이혜원: +이지영: []() + ```text ## 문제: [문제명](링크) diff --git "a/.github/ISSUE_TEMPLATE/\354\204\240\355\203\235-\353\254\270\354\240\234-\355\205\234\355\224\214\353\246\277.md" "b/.github/ISSUE_TEMPLATE/\354\204\240\355\203\235-\353\254\270\354\240\234-\355\205\234\355\224\214\353\246\277.md" new file mode 100644 index 00000000..50dbb11c --- /dev/null +++ "b/.github/ISSUE_TEMPLATE/\354\204\240\355\203\235-\353\254\270\354\240\234-\355\205\234\355\224\214\353\246\277.md" @@ -0,0 +1,22 @@ +--- +name: 선택 문제 템플릿 +about: 스터디 선택 문제 템플릿 입니다 +title: "[X주차_선택문제] 문제명" +labels: 'free' +assignees: '' + +--- + +- 사이트: 코드트리(CT) / 백준(BOJ) / 프로그래머스(PG) 중 하나를 선택 해 주세요 +- 문제: [문제명](링크) +- 번호: 없을 경우 삭제 +- 레벨: 없을 경우 삭제 +- 년도: 없을 경우 삭제 + +``` +### 🤔 시간복잡도 고려사항 + + + +### 💡 풀이 아이디어 +``` diff --git a/.github/auto_assign.yml b/.github/auto_assign.yml new file mode 100644 index 00000000..34884b50 --- /dev/null +++ b/.github/auto_assign.yml @@ -0,0 +1,25 @@ +# Set to true to add reviewers to pull requests +#addReviewers: true + +# Set to true to add assignees to pull requests +addAssignees: author + +# A list of reviewers to be added to pull requests (GitHub user name) +#reviewers: +# - GREEN +# - RED +# - BLUE +# - YELLOW + +# A number of reviewers added to the pull request +# Set 0 to add all the reviewers (default: 0) +#numberOfReviewers: 3 + +# A number of assignees to add to the pull request +# Set to 0 to add all of the assignees. +# Uses numberOfReviewers if unset. +numberOfAssignees: 1 + +# A list of keywords to be skipped the process that add reviewers if pull requests include it +#skipKeywords: +# - wip \ No newline at end of file diff --git "a/BOJ/1000-5000\353\262\210/JM_1135.java" "b/BOJ/1000-5000\353\262\210/JM_1135.java" new file mode 100644 index 00000000..1118d4fe --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JM_1135.java" @@ -0,0 +1,56 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.PriorityQueue; +import java.util.StringTokenizer; + +/** + * 완전 틀림, 해결책 제시 X + */ +public class JM_1135 { + static class Node { + int num; + int time; + + public Node(int num, int time) { + this.num = num; + this.time = time; + } + } + static int N; + static ArrayList[] trees; + + private static int dfs(int curr) { + int maxTime = 0; + PriorityQueue queue = new PriorityQueue<>((o1, o2) -> o2.time - o1.time); + for(int next: trees[curr]) { + int nextTime = dfs(next); + queue.offer(new Node(next, nextTime)); + } + + int t = 1; + while(!queue.isEmpty()) { + Node next = queue.poll(); + maxTime = Math.max(maxTime, next.time + t); + t++; + } + + return maxTime; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + trees = new ArrayList[N]; + + st = new StringTokenizer(br.readLine()); + for (int i = 0; i < N; i++) { + trees[i] = new ArrayList<>(); + int parent = Integer.parseInt(st.nextToken()); + if(parent != -1) trees[parent].add(i); + } + System.out.println(dfs(0)); + } +} diff --git "a/BOJ/1000-5000\353\262\210/JM_1450.java" "b/BOJ/1000-5000\353\262\210/JM_1450.java" new file mode 100644 index 00000000..c1b4f243 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JM_1450.java" @@ -0,0 +1,72 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.StringTokenizer; + +/** + * 완전 틀림, 해결책 제시 X + */ +public class JM_1450 { + static int N; + static int C; + static int[] W; + + private static int upperBound(int target, List A) { + int lo = 0; + int hi = A.size() - 1; + int ans = A.size(); + while (lo <= hi) { + int mid = (lo + hi) / 2; + if(target < A.get(mid)) { + ans = mid; + hi = mid - 1; + } + else lo = mid + 1; + } + return ans; + } + + private static void combi(int start, int end, int sum, List combiSums) { + if(sum > C) return; + if(start == end) { + combiSums.add(sum); + return; + } + combi(start + 1, end, sum, combiSums); + combi(start + 1, end, sum + W[start], combiSums); + } + + private static int solve() { + List left = new ArrayList<>(); + List right = new ArrayList<>(); + + combi(0, N / 2, 0, left); + combi(N / 2, N, 0, right); + + Collections.sort(right); + + int count = 0; + for(int leftSum : left) { + count += upperBound(C - leftSum, right); + } + return count; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + C = Integer.parseInt(st.nextToken()); + W = new int[N]; + + st = new StringTokenizer(br.readLine()); + for (int i = 0; i < N; i++) { + W[i] = Integer.parseInt(st.nextToken()); + } + + System.out.println(solve()); + } +} diff --git "a/BOJ/1000-5000\353\262\210/JM_1644.java" "b/BOJ/1000-5000\353\262\210/JM_1644.java" new file mode 100644 index 00000000..c188263a --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JM_1644.java" @@ -0,0 +1,56 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.StringTokenizer; + +public class JM_1644 { + static int N; + static List primeNumbers; + + private static void findPrimeNumber() { + boolean[] isPrime = new boolean[N + 1]; + Arrays.fill(isPrime, true); + + for (int i = 2; i <= Math.sqrt(N); i++) { + if(!isPrime[i]) continue; + for(int j = i * i; j <= N; j += i) { + isPrime[j] = false; + } + } + + for (int i = 2; i <= N; i++) { + if(isPrime[i]) primeNumbers.add(i); + } + } + + private static int solve() { + primeNumbers = new ArrayList<>(); + findPrimeNumber(); + + int count = 0; + int lo = 0, hi = 0; + int sum = 0; + while (true) { + if(sum < N) { + if(hi == primeNumbers.size()) break; + sum += primeNumbers.get(hi++); + } + else { + sum -= primeNumbers.get(lo++); + } + + if(sum == N) count++; + } + return count; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + System.out.println(solve()); + } +} diff --git "a/BOJ/1000-5000\353\262\210/JM_1707.java" "b/BOJ/1000-5000\353\262\210/JM_1707.java" new file mode 100644 index 00000000..86dcd8ee --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JM_1707.java" @@ -0,0 +1,56 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +public class JM_1707 { + static int V; + static int E; + static List> graph; + + private static boolean dfs(int g, int curr, int[] groups) { + groups[curr] = g; + for(int next : graph.get(curr)) { + if(groups[curr] == groups[next]) return false; + if(groups[next] == 0 && !dfs(3 - g, next, groups)) return false; + } + return true; + } + + private static boolean isBinaryGraph() { + int[] groups = new int[V + 1]; + for (int i = 1; i <= V; i++) { + if(groups[i] != 0) continue; + if(!dfs(1, i, groups)) return false; + } + return true; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + int K = Integer.parseInt(st.nextToken()); + + StringBuilder sb = new StringBuilder(); + while (K-- > 0) { + st = new StringTokenizer(br.readLine()); + V = Integer.parseInt(st.nextToken()); + E = Integer.parseInt(st.nextToken()); + graph = new ArrayList<>(); + for (int i = 0; i <= V; i++) { + graph.add(new ArrayList<>()); + } + for (int i = 0; i < E; i++) { + st = new StringTokenizer(br.readLine()); + int u = Integer.parseInt(st.nextToken()); + int v = Integer.parseInt(st.nextToken()); + graph.get(u).add(v); + graph.get(v).add(u); + } + sb.append(isBinaryGraph() ? "YES" : "NO").append("\n"); + } + System.out.println(sb); + } +} diff --git "a/BOJ/1000-5000\353\262\210/JM_2151.java" "b/BOJ/1000-5000\353\262\210/JM_2151.java" new file mode 100644 index 00000000..54d0423a --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JM_2151.java" @@ -0,0 +1,84 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.PriorityQueue; +import java.util.StringTokenizer; + +public class JM_2151 { + static class Point implements Comparable { + int y, x; + int dir; + int dist; + + public Point(int y, int x, int dir, int dist) { + this.y = y; + this.x = x; + this.dir = dir; + this.dist = dist; + } + + @Override + public int compareTo(Point o) { + return this.dist - o.dist; + } + } + static int N; + static char[][] map; + static Point start; + static Point end; + static final int[][] DIR = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}}; + + private static boolean inRange(int y, int x) { + return 0 <= y && y < N && 0 <= x && x < N; + } + + private static int solve() { + PriorityQueue pq = new PriorityQueue<>(); + boolean[][][] visited = new boolean[N][N][4]; + + for (int i = 0; i < 4; i++) { + pq.add(new Point(start.y, start.x, i, 0)); + } + + while (!pq.isEmpty()) { + Point curr = pq.poll(); + + visited[curr.y][curr.x][curr.dir] = true; + + if(curr.y == end.y && curr.x == end.x) return curr.dist; + + int ny = curr.y + DIR[curr.dir][0]; + int nx = curr.x + DIR[curr.dir][1]; + + if(!inRange(ny, nx) || map[ny][nx] == '*' || visited[ny][nx][curr.dir]) continue; + + if(map[ny][nx] == '!') { + pq.add(new Point(ny, nx, (curr.dir + 1) % 4, curr.dist + 1)); + pq.add(new Point(ny, nx, (curr.dir + 3) % 4, curr.dist + 1)); + } + pq.add(new Point(ny, nx, curr.dir, curr.dist)); + + } + + return -1; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + + map = new char[N][N]; + for (int i = 0; i < N; i++) { + map[i] = br.readLine().toCharArray(); + for (int j = 0; j < N; j++) { + if(map[i][j] == '#') { + if(start == null) start = new Point(i, j, -1, 0); + else end = new Point(i, j, -1, 0); + } + } + } + + System.out.println(solve()); + } +} diff --git "a/BOJ/1000-5000\353\262\210/JM_2629.java" "b/BOJ/1000-5000\353\262\210/JM_2629.java" new file mode 100644 index 00000000..d294201e --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JM_2629.java" @@ -0,0 +1,49 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +public class JM_2629 { + static int N; + static int[] W; + static int M; + static int maxW; + static boolean[][] dp; + + private static void solve() { + for (int i = 1; i <= N; i++) { + dp[i][W[i]] = true; + for (int j = 1; j <= maxW; j++) { + if(dp[i - 1][j]) dp[i][j] = true; + if(j + W[i] <= maxW && dp[i - 1][j + W[i]]) dp[i][j] = true; + if(dp[i - 1][Math.abs(j - W[i])]) dp[i][j] = true; + } + } + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + W = new int[N + 1]; + st = new StringTokenizer(br.readLine()); + for (int i = 1; i <= N; i++) { + W[i] = Integer.parseInt(st.nextToken()); + maxW += W[i]; + } + + dp = new boolean[N + 1][maxW + 1]; + solve(); + + StringBuilder sb = new StringBuilder(); + st = new StringTokenizer(br.readLine()); + M = Integer.parseInt(st.nextToken()); + st = new StringTokenizer(br.readLine()); + for (int i = 0; i < M; i++) { + int bead = Integer.parseInt(st.nextToken()); + if(bead > maxW) sb.append("N").append(" "); + else sb.append(dp[N][bead] ? "Y" : "N").append(" "); + } + System.out.println(sb); + } +} diff --git "a/BOJ/1000-5000\353\262\210/JM_3151.java" "b/BOJ/1000-5000\353\262\210/JM_3151.java" new file mode 100644 index 00000000..c808705d --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JM_3151.java" @@ -0,0 +1,65 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Arrays; +import java.util.StringTokenizer; + +public class JM_3151 { + static int N; + static int[] A; + + private static int lowerBound(int startIndex, int target) { + int lo = startIndex, hi = N - 1; + int ans = N; + while (lo <= hi){ + int mid = (lo + hi) / 2; + if(target <= A[mid]) { + ans = mid; + hi = mid - 1; + } + else lo = mid + 1; + } + return ans; + } + + private static int upperBound(int startIndex, int target) { + int lo = startIndex, hi = N - 1; + int ans = N; + while (lo <= hi){ + int mid = (lo + hi) / 2; + if(target < A[mid]) { + ans = mid; + hi = mid - 1; + } + else lo = mid + 1; + } + return ans; + } + + private static long solve() { + Arrays.sort(A); + long count = 0; + for (int i = 0; i < N; i++) { + for (int j = i + 1; j < N; j++) { + int target = 0 - (A[i] + A[j]); + int lowerIndex = lowerBound(j + 1, target); + int upperIndex = upperBound(j + 1, target); + count += upperIndex - lowerIndex; + } + } + return count; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + + A = new int[N]; + st = new StringTokenizer(br.readLine()); + for(int i = 0; i < N; i++) { + A[i] = Integer.parseInt(st.nextToken()); + } + System.out.println(solve()); + } +} diff --git "a/BOJ/1000-5000\353\262\210/JW_1135.java" "b/BOJ/1000-5000\353\262\210/JW_1135.java" new file mode 100644 index 00000000..11b8fc9d --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JW_1135.java" @@ -0,0 +1,53 @@ +import java.util.ArrayList; +import java.util.Collections; + +public class JW_1135 { + + static int n; + static int[] dp; + static ArrayList> tree = new ArrayList<>(); + + public static void main(String[] args) throws Exception { + n = read(); + dp = new int[n]; + // 트리 구조 만들기 + for (int i = 0; i < n; i++) { + tree.add(new ArrayList<>()); + int parent = read(); + // 루트 제외 + if (parent == -1) + continue; + tree.get(parent).add(i); + } + recursive(0); + System.out.println(dp[0]); + } + + // 재귀적으로 해당 노드가 걸리는 계산 + private static void recursive(int cur) { + ArrayList al = new ArrayList<>(); + for (int next : tree.get(cur)) { + recursive(next); + al.add(dp[next]); // 탐색한 노드가 가지는 값을 저장 + } + // 그리디하게, 가장 오래 걸리는 노드를 먼저 탐색해줘야 함 + al.sort(Collections.reverseOrder()); + + // 1초에 한 번씩 전파 가능 + // 최댓값이 결국 최솟값이 됨 + for (int i = 0; i < al.size(); i++) + dp[cur] = Math.max(dp[cur], al.get(i) + i + 1); + } + + private static int read() throws Exception { + int c, n = System.in.read() & 15; + boolean m = n == 13; + if (m) + n = System.in.read() & 15; + while ((c = System.in.read()) >= 48) + n = (n << 3) + (n << 1) + (c & 15); + if (c == 13) + System.in.read(); + return m ? ~n + 1 : n; + } +} diff --git "a/BOJ/1000-5000\353\262\210/JW_1450.java" "b/BOJ/1000-5000\353\262\210/JW_1450.java" new file mode 100644 index 00000000..ccb569ae --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JW_1450.java" @@ -0,0 +1,73 @@ +import java.util.Map; +import java.util.TreeMap; + +public class JW_1450 { + + static int n, c; + static TreeMap tmA = new TreeMap<>(); + static TreeMap tmB = new TreeMap<>(); + static TreeMap prefixSumA = new TreeMap<>(); + static TreeMap prefixSumB = new TreeMap<>(); + + public static void main(String[] args) throws Exception { + n = read(); + c = read(); + int[] aArr = new int[n / 2]; + int[] bArr = new int[n - n / 2]; + + for (int i = 0; i < aArr.length; i++) + aArr[i] = read(); + for (int i = 0; i < bArr.length; i++) + bArr[i] = read(); + recursive(0, 0, aArr, tmA); + recursive(0, 0, bArr, tmB); + + makePrefixSum(tmA, prefixSumA); + makePrefixSum(tmB, prefixSumB); + + System.out.println(calculate()); + } + + private static void recursive(int depth, long sum, int[] arr, TreeMap map) { + if (sum > c) + return; + if (depth == arr.length) { + map.put(sum, map.getOrDefault(sum, 0) + 1); + return; + } + recursive(depth + 1, sum + arr[depth], arr, map); + recursive(depth + 1, sum, arr, map); + } + + private static void makePrefixSum(TreeMap tm, TreeMap prefixSum) { + int sum = 0; + for (Map.Entry entry : tm.entrySet()) { + sum += entry.getValue(); + prefixSum.put(entry.getKey(), sum); + } + } + + private static long calculate() { + long count = 0; + + for (Map.Entry entry : tmA.entrySet()) { + long aSum = entry.getKey(); + int aWays = entry.getValue(); + Map.Entry bEntry = prefixSumB.floorEntry(c - aSum); + if (bEntry != null) { + count += (long) aWays * bEntry.getValue(); + } + } + + return count; + } + + private static int read() throws Exception { + int c, n = System.in.read() & 15; + while ((c = System.in.read()) >= 48) + n = (n << 3) + (n << 1) + (c & 15); + if (c == 13) + System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/BOJ/1000-5000\353\262\210/JW_1644.java" "b/BOJ/1000-5000\353\262\210/JW_1644.java" new file mode 100644 index 00000000..bd2b2991 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JW_1644.java" @@ -0,0 +1,36 @@ +import java.util.ArrayList; + +public class JW_1644 { + + public static void main(String[] args) throws Exception { + int n = read(); + int cnt = 0; + boolean[] isPrime = new boolean[n + 1]; + isPrime[0] = isPrime[1] = true; + ArrayList prime = new ArrayList<>(); + for (int i = 2; i < n + 1; i++) { + if (isPrime[i]) + continue; + prime.add(i); + for (int j = i * 2; j < n + 1; j += i) + isPrime[j] = true; + } + int l = 0, r = 0, sum = 0; + while (r < prime.size()) { + sum += prime.get(r); + while (sum > n && l <= r) + sum -= prime.get(l++); + if (sum == n) + cnt++; + r++; + } + System.out.println(cnt); + } + + private static int read() throws Exception { + int c, n = System.in.read() & 15; + while ((c = System.in.read()) >= 48) + n = (n << 3) + (n << 1) + (c & 15); + return n; + } +} \ No newline at end of file diff --git "a/BOJ/1000-5000\353\262\210/JW_1707.java" "b/BOJ/1000-5000\353\262\210/JW_1707.java" new file mode 100644 index 00000000..d01ff10c --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JW_1707.java" @@ -0,0 +1,62 @@ +import java.util.ArrayList; + +public class JW_1707 { + + static int v, e; + static ArrayList> edges; + static int[] groups; + + public static void main(String[] args) throws Exception { + int k = read(); + StringBuilder sb = new StringBuilder(); + while (k-- > 0) { + init(); + boolean isBipartite = true; // 이분 그래프인지 판단하는 플래그 + // 방문하지 않은 점에 대해서 이분 그래프인지 판단 + for (int i = 1; i < v + 1; i++) + if (groups[i] == 0) + if (!dfs(i, 1)) { + isBipartite = false; + break; + } + sb.append(isBipartite ? "YES\n" : "NO\n"); + } + System.out.println(sb); + } + + private static boolean dfs(int node, int group) { + groups[node] = group; // 현재 노드 넘버링 + for (int next : edges.get(node)) + if (groups[next] == 0) { + // 그래프에 모순이 발생하면 false 반환 + if (!dfs(next, 3 - group)) + return false; + // 그래프에 모순이 발생하면 false 반환 + } else if (groups[next] == group) + return false; + return true; + } + + private static void init() throws Exception { + v = read(); + e = read(); + groups = new int[v + 1]; + edges = new ArrayList<>(); + for (int i = 0; i < v + 1; i++) + edges.add(new ArrayList<>()); + for (int i = 0; i < e; i++) { + int v = read(), u = read(); + edges.get(v).add(u); + edges.get(u).add(v); + } + } + + private static int read() throws Exception { + int c, n = System.in.read() & 15; + while ((c = System.in.read()) >= 48) + n = (n << 3) + (n << 1) + (c & 15); + if (c == 13) + System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/BOJ/1000-5000\353\262\210/JW_1939.java" "b/BOJ/1000-5000\353\262\210/JW_1939.java" new file mode 100644 index 00000000..4a5de93f --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JW_1939.java" @@ -0,0 +1,56 @@ +import java.util.PriorityQueue; + +public class JW_1939 { + + static int[] parent, rank; + + public static void main(String[] args) throws Exception { + int n = read(), m = read(); + parent = new int[n + 1]; + rank = new int[n + 1]; + for (int i = 0; i < n + 1; i++) + parent[i] = i; + PriorityQueue pq = new PriorityQueue<>((o1, o2) -> o2[2] - o1[2]); + for (int i = 0; i < m; i++) + pq.offer(new int[] { read(), read(), read() }); + int s = read(), e = read(); + int maxWeight = 0; + while (find(s) != find(e)) { + int[] edge = pq.poll(); + if (union(edge[0], edge[1])) + maxWeight = edge[2]; + } + System.out.println(maxWeight); + } + + private static boolean union(int y, int x) { + int rootX = find(x), rootY = find(y); + if (rootX != rootY) { + if (rank[rootX] < rank[rootY]) + parent[rootX] = rootY; + else if (rank[rootX] > rank[rootY]) + parent[rootY] = parent[rootX]; + else { + parent[rootY] = rootX; + rank[rootX]++; + } + return true; + } + return false; + } + + private static int find(int x) { + if (parent[x] == x) + return parent[x]; + return parent[x] = find(parent[x]); + } + + private static int read() throws Exception { + int c, n = System.in.read() & 15; + while ((c = System.in.read()) >= 48) + n = (n << 3) + (n << 1) + (c & 15); + if (c == 13) + System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/BOJ/1000-5000\353\262\210/JW_2151.java" "b/BOJ/1000-5000\353\262\210/JW_2151.java" new file mode 100644 index 00000000..3fcf16d6 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JW_2151.java" @@ -0,0 +1,63 @@ +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.ArrayDeque; +import java.util.Deque; + +public class JW_2151 { + + static int n, sy, sx, sd, ey, ex; + static char[][] board; + static boolean[][] visited; + static int[] dy = { -1, 1, 0, 0 }, dx = { 0, 0, -1, 1 }; + + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + n = Integer.parseInt(br.readLine()); + board = new char[n][n]; + visited = new boolean[n][n]; + boolean find = false; + for (int i = 0; i < n; i++) { + String line = br.readLine(); + for (int j = 0; j < n; j++) { + board[i][j] = line.charAt(j); + if (board[i][j] == '#') + if (!find) { + sy = i; + sx = j; + find = true; + } else { + ey = i; + ex = j; + } + } + } + Deque dq = new ArrayDeque<>(); + dq.offer(new int[] { sy, sx, 0 }); + visited[sy][sx] = true; + while (!dq.isEmpty()) { + int[] cur = dq.poll(); + int y = cur[0], x = cur[1], cnt = cur[2]; + for (int i = 0; i < 4; i++) { + int ny = y + dy[i], nx = x + dx[i]; + // 직선 움직임 + while (isValid(ny, nx) && board[ny][nx] != '*') { + // 거울을 놓을 수 있는 위치라면 큐 삽입 + if (!visited[ny][nx] && board[ny][nx] == '!') { + visited[ny][nx] = true; + dq.offer(new int[] { ny, nx, cnt + 1 }); + // 종료 조건 + } else if (ny == ey && nx == ex) { + System.out.println(cnt); + return; + } + ny = ny + dy[i]; + nx = nx + dx[i]; + } + } + } + } + + private static boolean isValid(int y, int x) { + return 0 <= y && y < n && 0 <= x && x < n; + } +} diff --git "a/BOJ/1000-5000\353\262\210/JW_2169.java" "b/BOJ/1000-5000\353\262\210/JW_2169.java" new file mode 100644 index 00000000..067ca435 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JW_2169.java" @@ -0,0 +1,42 @@ +public class JW_2169 { + + public static void main(String[] args) throws Exception { + int n = read(), m = read(); + int[][] arr = new int[n][m]; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) + arr[i][j] = read(); + } + int[][] dp = new int[3][m]; + // DP 배열 초기화 + dp[0][0] = arr[0][0]; + for (int i = 1; i < m; i++) + dp[0][i] = dp[0][i - 1] + arr[0][i]; + for (int i = 1; i < n; i++) { + for (int j = 0; j < m; j++) + dp[1][j] = dp[2][j] = dp[0][j] + arr[i][j]; // 아래로 내려오는 경우 + // 오른쪽 누적합 계산 및 최댓값 갱신 + for (int j = 1; j < m; j++) + dp[1][j] = Math.max(dp[1][j], dp[1][j - 1] + arr[i][j]); + // 왼쪽 누적합 계산 및 최댓값 갱신 + for (int j = m - 2; j >= 0; j--) + dp[2][j] = Math.max(dp[2][j], dp[2][j + 1] + arr[i][j]); + // 전체 최댓값 갱신 + for (int j = 0; j < m; j++) + dp[0][j] = Math.max(dp[1][j], dp[2][j]); + } + System.out.println(dp[0][m - 1]); + } + + private static int read() throws Exception { + int c, n = System.in.read() & 15; + boolean m = n == 13; + if (m) + n = System.in.read() & 15; + while ((c = System.in.read()) >= 48) + n = (n << 3) + (n << 1) + (c & 15); + if (c == 13) + System.in.read(); + return m ? ~n + 1 : n; + } +} diff --git "a/BOJ/1000-5000\353\262\210/JW_2170.java" "b/BOJ/1000-5000\353\262\210/JW_2170.java" new file mode 100644 index 00000000..05f8c7fc --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JW_2170.java" @@ -0,0 +1,37 @@ +import java.util.Arrays; + +public class JW_2170 { + + public static void main(String[] args) throws Exception { + int n = read(); + int[][] arr = new int[n][2]; + for (int i = 0; i < n; i++) + arr[i] = new int[] { read(), read() }; + Arrays.sort(arr, (o1, o2) -> o1[0] - o2[0]); + int totalLen = 0, sPos = arr[0][0], ePos = arr[0][1]; + for (int i = 1; i < n; i++) { + if (arr[i][0] <= ePos) { + sPos = Math.min(sPos, arr[i][0]); + ePos = Math.max(ePos, arr[i][1]); + } else { + totalLen += ePos - sPos; + sPos = arr[i][0]; + ePos = arr[i][1]; + } + } + totalLen += ePos - sPos; + System.out.println(totalLen); + } + + private static int read() throws Exception { + int c, n = System.in.read() & 15; + boolean m = n == 13; + if (m) + n = System.in.read() & 15; + while ((c = System.in.read()) >= 48) + n = (n << 3) + (n << 1) + (c & 15); + if (c == 13) + System.in.read(); + return m ? ~n + 1 : n; + } +} \ No newline at end of file diff --git "a/BOJ/1000-5000\353\262\210/JW_2504.java" "b/BOJ/1000-5000\353\262\210/JW_2504.java" new file mode 100644 index 00000000..c4c04302 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JW_2504.java" @@ -0,0 +1,46 @@ +import java.io.BufferedReader; +import java.io.InputStreamReader; + +public class JW_2504 { + + static String str; + static int idx = 0; + + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + str = br.readLine(); + int value = recursive(); + if (value == -1 || idx != str.length()) + System.out.println(0); + else + System.out.println(value); + } + + private static int recursive() { + int sum = 0; + while (idx < str.length()) { + char c = str.charAt(idx); + if (c == '(' || c == '[') { + char openC = c; + idx++; + int value = recursive(); + if (value == -1 || idx == str.length()) + return -1; + char closeC = str.charAt(idx); + idx++; + if (!isValid(openC, closeC)) + return -1; + if (value == 0) + sum += openC == '(' ? 2 : 3; + else + sum += openC == '(' ? value * 2 : value * 3; + } else + break; + } + return sum; + } + + private static boolean isValid(char openC, char closeC) { + return (openC == '(' && closeC == ')') || (openC == '[' && closeC == ']'); + } +} \ No newline at end of file diff --git "a/BOJ/1000-5000\353\262\210/JW_2629.java" "b/BOJ/1000-5000\353\262\210/JW_2629.java" new file mode 100644 index 00000000..34f71a29 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JW_2629.java" @@ -0,0 +1,47 @@ +public class JW_2629 { + + public static void main(String[] args) throws Exception { + int n = read(); + int[] weights = new int[n + 1]; + for (int i = 1; i < n + 1; i++) + weights[i] = read(); + int m = read(), maxTarget = 0; + int[] targets = new int[m]; + for (int i = 0; i < m; i++) { + targets[i] = read(); + maxTarget = Math.max(maxTarget, targets[i]); + } + // 가능한 범위까지 DP 배열 생성 + boolean[] dp = new boolean[maxTarget + 501]; + dp[0] = true; + int w; + for (int i = 1; i < n + 1; i++) { + w = weights[i]; + boolean[] temp = dp.clone(); // 영향을 주지 않기 위해 새로운 배열 생성 + for (int j = dp.length - 1; j >= 0; j--) { + if (dp[j]) { + if (j + w < dp.length) + temp[j + w] = true; // 더하기 + if (j - w >= 0) + temp[j - w] = true; // 뺴기 + if (w - j >= 0) + temp[w - j] = true; // 반대편에 놓기 + } + } + dp = temp; + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < m; i++) + sb.append(dp[targets[i]] ? 'Y' : 'N').append(' '); + System.out.println(sb); + } + + private static int read() throws Exception { + int c, n = System.in.read() & 15; + while ((c = System.in.read()) >= 48) + n = (n << 3) + (n << 1) + (c & 15); + if (c == 13) + System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/BOJ/1000-5000\353\262\210/JW_2931.java" "b/BOJ/1000-5000\353\262\210/JW_2931.java" new file mode 100644 index 00000000..5fa9ce74 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JW_2931.java" @@ -0,0 +1,109 @@ +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +public class JW_2931 { + + static int r, c; + static boolean[][][] board; + static boolean[][] placed; + + static int[] dy = { -1, 1, 0, 0 }, dx = { 0, 0, -1, 1 }; + static int[] opposite = { 1, 0, 3, 2 }; + + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + r = Integer.parseInt(st.nextToken()); + c = Integer.parseInt(st.nextToken()); + board = new boolean[r][c][4]; + placed = new boolean[r][c]; + for (int i = 0; i < r; i++) { + String line = br.readLine(); + for (int j = 0; j < c; j++) { + char pipe = line.charAt(j); + if (pipe != '.') { + place(i, j, pipe); + placed[i][j] = true; + } + } + } + int missingY = -1, missingX = -1; + boolean[] deleted = new boolean[4]; + for (int i = 0; i < r; i++) { + for (int j = 0; j < c; j++) { + if (placed[i][j]) + continue; + boolean[] connections = new boolean[4]; + for (int k = 0; k < 4; k++) { + int ny = i + dy[k], nx = j + dx[k]; + if (!isValid(ny, nx)) + continue; + if (!placed[ny][nx]) + continue; + if (board[ny][nx][opposite[k]]) { + connections[k] = true; + } + } + int count = 0; + for (boolean conn : connections) { + if (conn) + count++; + } + if (count >= 2) { + missingY = i; + missingX = j; + deleted = connections; + } + } + } + String recoveredPipe = find(deleted); + System.out.println((missingY + 1) + " " + (missingX + 1) + " " + recoveredPipe); + } + + private static String find(boolean[] deleted) { + if (deleted[0] && deleted[1] && !deleted[2] && !deleted[3]) + return "|"; + if (!deleted[0] && !deleted[1] && deleted[2] && deleted[3]) + return "-"; + if (deleted[0] && deleted[1] && deleted[2] && deleted[3]) + return "+"; + if (!deleted[0] && deleted[1] && !deleted[2] && deleted[3]) + return "1"; + if (deleted[0] && !deleted[1] && !deleted[2] && deleted[3]) + return "2"; + if (deleted[0] && !deleted[1] && deleted[2] && !deleted[3]) + return "3"; + return "4"; + } + + private static void place(int y, int x, char pipe) { + switch (pipe) { + case '|': + board[y][x] = new boolean[] { true, true, false, false }; + break; + case '-': + board[y][x] = new boolean[] { false, false, true, true }; + break; + case '+': + board[y][x] = new boolean[] { true, true, true, true }; + break; + case '1': + board[y][x] = new boolean[] { false, true, false, true }; + break; + case '2': + board[y][x] = new boolean[] { true, false, false, true }; + break; + case '3': + board[y][x] = new boolean[] { true, false, true, false }; + break; + case '4': + board[y][x] = new boolean[] { false, true, true, false }; + break; + } + } + + private static boolean isValid(int y, int x) { + return 0 <= y && y < r && 0 <= x && x < c; + } +} \ No newline at end of file diff --git "a/BOJ/1000-5000\353\262\210/JW_3151.java" "b/BOJ/1000-5000\353\262\210/JW_3151.java" new file mode 100644 index 00000000..bbb535eb --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JW_3151.java" @@ -0,0 +1,52 @@ +import java.util.Arrays; + +public class JW_3151 { + + static int n; + static int[] arr; + + public static void main(String[] args) throws Exception { + n = read(); + arr = new int[n]; + for (int i = 0; i < n; i++) + arr[i] = read(); + Arrays.sort(arr); + long cnt = 0; + for (int i = 0; i < n - 1; i++) { + if (arr[i] > 0) + break; + for (int j = i + 1; j < n; j++) { + int target = arr[i] + arr[j]; + int upperIndex = getBound(j + 1, -target, true); + int lowerIndex = getBound(j + 1, -target, false); + cnt += upperIndex - lowerIndex; + } + } + System.out.println(cnt); + } + + private static int getBound(int s, int target, boolean flag) { + int l = s, r = n; + while (l < r) { + int mid = (l + r) / 2; + if (arr[mid] < target || (flag && arr[mid] == target)) { + l = mid + 1; + } else { + r = mid; + } + } + return l; + } + + private static int read() throws Exception { + int c, n = System.in.read() & 15; + boolean m = n == 13; + if (m) + n = System.in.read() & 15; + while ((c = System.in.read()) >= 48) + n = (n << 3) + (n << 1) + (c & 15); + if (c == 13) + System.in.read(); + return m ? ~n + 1 : n; + } +} diff --git "a/BOJ/1000-5000\353\262\210/JY_1135.java" "b/BOJ/1000-5000\353\262\210/JY_1135.java" new file mode 100644 index 00000000..df1f0410 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JY_1135.java" @@ -0,0 +1,59 @@ +package dfs; +import java.io.*; +import java.util.*; + +public class JY_1135 { + + static int N; + static List[] g; + static int[] time; + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + g = new ArrayList[N]; + + for (int i = 0; i < N; i++) { + g[i] = new ArrayList<>(); + } + + st = new StringTokenizer(br.readLine()); + for (int i = 0; i < N; i++) { + int p = Integer.parseInt(st.nextToken()); + if (p != -1) { + g[p].add(i); + } + } + + // 최소 시간 계산 + System.out.println(dfs(0)); + } + + public static int dfs(int node) { + // 리프노드이면 전달시간 0 반환 + if (g[node].isEmpty()) { + return 0; + } + + + List tList = new ArrayList<>(); + + // 내 자식에게 전파할 수 있는 총 시간 구하기 + for (int child : g[node]) { + tList.add(dfs(child)); + } + + // 전파 시간이 긴 순으로 정렬 + Collections.sort(tList, (o1, o2)-> o2-o1); + + int maxTime = 0; + for (int i = 0; i < tList.size(); i++) { + // 순차적으로 전화를 걸면서, 현재 전화받은 자식 기준으로 시간 계산 + maxTime = Math.max(maxTime, tList.get(i) + i + 1); + } + + return maxTime; + } +} diff --git "a/BOJ/1000-5000\353\262\210/JY_1450.java" "b/BOJ/1000-5000\353\262\210/JY_1450.java" new file mode 100644 index 00000000..013022a7 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JY_1450.java" @@ -0,0 +1,71 @@ +import java.io.*; +import java.util.*; +public class JY_1450 { + + static int N, C; + static int[] arr; + static List left; + static List right; + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + C = Integer.parseInt(st.nextToken()); + + arr = new int[N]; + st = new StringTokenizer(br.readLine()); + for(int i=0; i(); + right = new ArrayList<>(); + comb(left, 0, N/2, 0); + comb(right, N/2, N, 0); + + // 오른쪽 부분합 정렬 + Collections.sort(right); + + int cnt = 0; + int idx = 0; + for(int i=0; i cList, int s, int e, int sum) { + // 최대 무게 C보다 크면 return + if(sum > C) return; + // 모두 탐색 + if(s == e) { + cList.add(sum); + return; + } + + // s번째 포함 X + comb(cList, s+1, e, sum); + // s번째 포함 O + comb(cList, s+1, e, sum+arr[s]); + } + public static int bs(int s, int e, int a) { + int ans = 0; + while(s <= e) { + int mid = (s + e) / 2; + if(right.get(mid) <= C - a) { + ans = mid; + s = mid + 1; + } else { + e = mid - 1; + } + } + return ans; + } + +} diff --git "a/BOJ/1000-5000\353\262\210/JY_1644.java" "b/BOJ/1000-5000\353\262\210/JY_1644.java" new file mode 100644 index 00000000..372a558c --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JY_1644.java" @@ -0,0 +1,64 @@ +import java.io.*; +import java.util.*; +public class JY_1644 { + + static int N; + static List pList; + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + + N = Integer.parseInt(br.readLine()); + pList = new ArrayList<>(); + findPrime(); + +// System.out.println(pList); + + if(N == 1) { + System.out.println(0); + return; + } + int s = 0; + int e = 0; + int total = pList.get(e); + int cnt = 0; + while(s <= e) { + if(total == N) { + cnt++; + total -= pList.get(s); + s++; + } + else if(total > N) { + total -= pList.get(s); + s++; + } + else { + e++; + if(e >= pList.size()) break; + total += pList.get(e); + } + } + + System.out.println(cnt); + + } + public static void findPrime() { + boolean[] isPrime = new boolean[N+1]; + Arrays.fill(isPrime, true); + isPrime[0] = false; + isPrime[1] = false; + + + for(int i = 2; i <= Math.sqrt(N); i++){ // 2부터 n의 제곱근까지의 모든 수를 확인 + if(isPrime[i]){ // 해당수가 소수라면, 해당수를 제외한 배수들을 모두 false 처리하기 + for(int j = i*i; j<= N; j += i){//그 이하의 수는 모두 검사했으므로 i*i부터 시작 + isPrime[j] = false; + } + } + } + for(int i=2; i[] g; + static boolean[] visited; + static int[] crr; + static boolean isOk; + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + T = Integer.parseInt(st.nextToken()); + StringBuilder sb = new StringBuilder(); + for(int t=0; t(); + } + + for(int i=0; i[] g; + static boolean[] visited; + static int ea, eb; + static boolean isOk; + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + + g = new ArrayList[N+1]; + for(int i=1; i(); + } + + int mc = 0; + for(int i=0; ieb로 갈 수 있는지 탐색 + canGo(ea, mid); + if(isOk) { + ans = mid; + s = mid + 1; + } else { + e = mid - 1; + } + + } + + System.out.println(ans); + } + public static void canGo(int now, int cost) { + if(now == eb) { + isOk = true; + return; + } + + visited[now] = true; + + for(int[] next : g[now]) { + if(visited[next[0]]) continue; + if(next[1] < cost) continue; + + canGo(next[0], cost); + } + + } + +} diff --git "a/BOJ/1000-5000\353\262\210/JY_2151.java" "b/BOJ/1000-5000\353\262\210/JY_2151.java" new file mode 100644 index 00000000..d6fc1d72 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JY_2151.java" @@ -0,0 +1,109 @@ +import java.io.*; +import java.util.*; +public class JY_2151 { + + static final int INF = Integer.MAX_VALUE; + static int N; + static char[][] g; + static int[][] cnt; + static int[][] doors; + // 상 좌 하 우 + static int[] dx = {-1, 0, 1, 0}; + static int[] dy = {0, -1, 0, 1}; + static int ans; + static class State { + int x, y, dir, cnt; + + public State(int x, int y, int dir, int cnt) { + super(); + this.x = x; + this.y = y; + this.dir = dir; + this.cnt = cnt; + } + + @Override + public String toString() { + return "State [x=" + x + ", y=" + y + ", dir=" + dir + ", cnt=" + cnt + "]"; + } + + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + g = new char[N][N]; + + doors = new int[2][2]; + int d = 0; + for(int i=0; i=0 && x=0 && y pq = new PriorityQueue<>((o1, o2)->o1.cnt-o2.cnt); + + cnt[sx][sy] = 0; + g[sx][sy] = '*'; + + // 초기에 갈 수 있는 방향 탐색 + for(int i=0; i<4; i++) { + int nx = sx + dx[i]; + int ny = sy + dy[i]; + if(!inRange(nx, ny)) continue; + if(g[nx][ny] == '*') continue; + pq.add(new State(sx, sy, i, 0)); + } + + while(!pq.isEmpty()) { + State now = pq.poll(); + + if(g[now.x][now.y] == '#') { + ans = now.cnt; + return; + } + int nx = now.x + dx[now.dir]; + int ny = now.y + dy[now.dir]; + + if(!inRange(nx, ny)) continue; + if(g[nx][ny] == '*') continue; + // 한 번이상 방문했고, 현재 저장된 회수보다 크다면 진행 X + if(cnt[nx][ny] != INF && cnt[nx][ny] >= now.cnt) continue; + + cnt[nx][ny] = now.cnt; + pq.add(new State(nx, ny, now.dir, now.cnt)); + + // 다음 칸이 거울 + if(g[nx][ny] == '!') { + pq.add(new State(nx, ny, (now.dir+1)%4, now.cnt+1)); + pq.add(new State(nx, ny, (now.dir+3)%4, now.cnt+1)); + } + } + + } + +} diff --git "a/BOJ/1000-5000\353\262\210/JY_2169.java" "b/BOJ/1000-5000\353\262\210/JY_2169.java" new file mode 100644 index 00000000..799d2899 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JY_2169.java" @@ -0,0 +1,59 @@ +import java.io.*; +import java.util.*; +public class JY_2169 { + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + int N = Integer.parseInt(st.nextToken()); + int M = Integer.parseInt(st.nextToken()); + int[][] g = new int[N+1][M+1]; + int[][] dp = new int[N+1][M+1]; + for(int i=1; i오 + int[] t1 = new int[M+1]; + // t2: 오-> 왼 + int[] t2 = new int[M+1]; + + t1[1] = dp[i-1][1] + g[i][1]; + for(int j=2; j=0; j--) { + t2[j] = Math.max(dp[i-1][j], t2[j+1]) + g[i][j]; + } + + // dp에 반영 + for(int j=1; j { + int x, y; + + public Pos(int x, int y) { + super(); + this.x = x; + this.y = y; + } + @Override + public int compareTo(Pos other) { + return this.x - other.x; + } + + @Override + public String toString() { + return "Pos [x=" + x + ", y=" + y + "]"; + } + + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + int N = Integer.parseInt(st.nextToken()); + + List pList = new ArrayList<>(); + for(int i=0; i end 갱신 + if(e >= now.x) { + e = Math.max(e, now.y); + } + // 겹치지 않는 경우 + else { + // 기존것 더해주고 새로 업데이트 + ans += (e - s); + s = now.x; + e = now.y; + } + } + ans += (e - s); + System.out.println(ans); + + } + +} diff --git "a/BOJ/1000-5000\353\262\210/JY_2504.java" "b/BOJ/1000-5000\353\262\210/JY_2504.java" new file mode 100644 index 00000000..7faad233 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/JY_2504.java" @@ -0,0 +1,51 @@ +import java.io.*; +import java.util.*; +public class JY_2504 { + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + + String line = br.readLine(); + + Stack stack = new Stack<>(); + + int ans = 0; + int tmp = 1; + for(int i=0; i=wrr[i]; j--) { + dp[j] = dp[j] + dp[j-wrr[i]]; + } + } + + for(int i=1; i maxW) { + sb.append("N "); + continue; + } + + // 구슬 --- 추(n개) + if(dp[c] != 0) { + sb.append("Y "); + } + // 구슬+추(n개) --- 추(m개) + else { + boolean isOk = false; + // 가지고 있는 추 n개로 만들수 있는 무게에 구슬을 더한 값이 + // 또 다른 추 m개로 만들 수 있는 무게값과 같은 것이 있는지 체크 + for(int j=1; j maxW) break; + if(dp[j] != 0 && dp[j+c] != 0) { + sb.append("Y "); + isOk = true; + break; + } + } + if(!isOk) sb.append("N "); + } + } + + System.out.println(sb.toString()); + + // case1) 2차원 +// int[][] dp = new int[N+1][maxW+1]; +// for(int i=0; i j) dp[i][j] = dp[i-1][j]; +// else { +// dp[i][j] = dp[i-1][j] + dp[i-1][j-wrr[i]]; +// } +// } +// } +// +// for(int i=1; i start && arr[b] == arr[end]) { + b--; + } + // 경우의 수 == (a ~ start의 개수) * (end ~ b의 개수) + ans += (a - start) * (end - b); + start = a; + end = b; + } + } + // 두 수의 합이 -(첫번쨰 수)보다 작음 : 합 증가해야 함 + else if (s < -arr[i]) { + start++; + } + // 두 수의 합이 -(첫번째 수)보다 큼 : 합을 감소해야 함 + else { + end--; + } + } + } + + System.out.println(ans); + + } + +} diff --git "a/BOJ/1000-5000\353\262\210/SB_1135.java" "b/BOJ/1000-5000\353\262\210/SB_1135.java" new file mode 100644 index 00000000..02d91c7e --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/SB_1135.java" @@ -0,0 +1,44 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.*; + +public class SB_1135 { + static int N; + static List> underling = new ArrayList<>(); + + private static int call(int node) { + ArrayList lst = new ArrayList<>(); + + if (underling.get(node).isEmpty()) { // 리프노드면 0반환 + return 0; + } + + for (int ud : underling.get(node)) { + lst.add(call(ud)); // 각 부하들의 전화단계 구하기 + } + + lst.sort(Collections.reverseOrder()); + for (int i = 0; i < lst.size(); i++) { + lst.set(i, lst.get(i) + i + 1); + } + + return Collections.max(lst); + } + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + N = Integer.parseInt(br.readLine()); + for (int i = 0; i < N; i++) { + underling.add(new ArrayList<>()); + } + + StringTokenizer st = new StringTokenizer(br.readLine()); + for (int i = 0; i < N; i++) { + int boss = Integer.parseInt(st.nextToken()); + if (boss==-1) continue; + underling.get(boss).add(i); + } + + System.out.println(call(0)); + } +} diff --git "a/BOJ/1000-5000\353\262\210/SB_1450.java" "b/BOJ/1000-5000\353\262\210/SB_1450.java" new file mode 100644 index 00000000..1aec719a --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/SB_1450.java" @@ -0,0 +1,76 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.StringTokenizer; + +public class SB_1450 { + static int N, C; + static int[] weigth; + static List sbLst = new ArrayList<>(); + static int ans = 0; + + private static int find(long x) { // upper-bound + int left = 0; + int right = sbLst.size(); + + while (left < right) { + int mid = (left + right) / 2; + if (sbLst.get(mid) <= x) left = mid + 1; + else right = mid; + } + return right; + } + + + private static void findSubSum(int depth, long sm) { + if (depth > N-1) { + ans += find(C-sm); // C-현재값 보다 작거나 같은 수 개수 찾기 + return; + } + + findSubSum(depth + 1, sm); + if (sm + weigth[depth] <= C) { + findSubSum(depth + 1, sm + weigth[depth]); + } + } + + private static void subSum(int depth, long sm) { + if (depth >= (N / 2)) { // 첫번째 그룹은 N/2의 값까지 포함되어야 함 + sbLst.add(sm); + return; + } + // 현재 원소 포함 + subSum(depth + 1, sm); + + // 현재 원소 미포함 + if (sm + weigth[depth] <= C) { + subSum(depth + 1, sm + weigth[depth]); + } + } + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + C = Integer.parseInt(st.nextToken()); + + weigth = new int[N]; + st = new StringTokenizer(br.readLine()); + for (int i = 0; i < N; i++) { + weigth[i] = Integer.parseInt(st.nextToken()); + } + + // 첫번째 그룹에서 만들 수 있는 모든 부분집합 합 만들기 + subSum(0, 0); + Collections.sort(sbLst); + + // 두번째 그룹에서도 만들 수 있는 모든 부분집합 합을 만들고, 위에서 만든 리스트에 C-x했을때 작거나 같은 값 수 찾기(이분탐색) + findSubSum(N / 2, 0); + + System.out.println(ans); + } + +} diff --git "a/BOJ/1000-5000\353\262\210/SB_1644.java" "b/BOJ/1000-5000\353\262\210/SB_1644.java" new file mode 100644 index 00000000..eb713035 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/SB_1644.java" @@ -0,0 +1,51 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; + +public class SB_1644 { + static int N; + static ArrayList primes = new ArrayList<>(); + + private static void getPrimeLst() { + boolean[] isPrime = new boolean[N + 1]; + Arrays.fill(isPrime, true); + + isPrime[0] = isPrime[1] = false; + for (int i = 2; i <= Math.sqrt(N); i++) { + if (isPrime[i]) { + for (int j = i * i; j <= N; j += i) { + isPrime[j] = false; + } + } + } + + for (int i = 2; i <= N; i++) { + if (isPrime[i]) primes.add(i); + } + } + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + N = Integer.parseInt(br.readLine()); + + getPrimeLst(); + + int s = 0, e = 0; + int cnt = 0; + int sum = 0; + + while (true) { + if (sum==N) cnt++; + if (sum < N) { + if (e == primes.size()) break; + sum += primes.get(e++); + } + else{ + sum -= primes.get(s++); + } + } + + System.out.println(cnt); + } +} diff --git "a/BOJ/1000-5000\353\262\210/SB_1707.java" "b/BOJ/1000-5000\353\262\210/SB_1707.java" new file mode 100644 index 00000000..f8dcb098 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/SB_1707.java" @@ -0,0 +1,71 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.*; + +public class SB_1707 { + static int[] visited; + static ArrayList> adj; + + private static boolean bfs(int node) { + Deque que = new ArrayDeque<>(); + que.offer(node); + visited[node] = 0; // 처음은 0으로 시작 + + while (!que.isEmpty()) { + int cur = que.poll(); + for (int nxt : adj.get(cur)) { + if (visited[nxt] == -1) { + visited[nxt] = visited[cur] ^ 1; // 다른 팀 배정 + que.offer(nxt); + } else if (visited[nxt] == visited[cur]) { + return false; // 같은 그룹이면 이분 그래프가 아님 + } + } + } + return true; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st; + StringBuilder sb = new StringBuilder(); + + int K = Integer.parseInt(br.readLine()); + while (K-- > 0) { + st = new StringTokenizer(br.readLine()); + int V = Integer.parseInt(st.nextToken()); + int E = Integer.parseInt(st.nextToken()); + + adj = new ArrayList<>(); + for (int i = 0; i <= V; i++) { + adj.add(new ArrayList<>()); + } + + for (int i = 0; i < E; i++) { + st = new StringTokenizer(br.readLine()); + int u = Integer.parseInt(st.nextToken()); + int v = Integer.parseInt(st.nextToken()); + adj.get(u).add(v); + adj.get(v).add(u); + } + + visited = new int[V + 1]; + Arrays.fill(visited, -1); + + boolean isBipartite = true; + for (int i = 1; i <= V; i++) { + if (visited[i] == -1) { // 방문하지 않은 노드가 있다면 새롭게 탐색 + if (!bfs(i)) { + isBipartite = false; + break; + } + } + } + + sb.append(isBipartite ? "YES\n" : "NO\n"); + } + + System.out.print(sb); + } +} diff --git "a/BOJ/1000-5000\353\262\210/SB_1939.java" "b/BOJ/1000-5000\353\262\210/SB_1939.java" new file mode 100644 index 00000000..a7bd3395 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/SB_1939.java" @@ -0,0 +1,73 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.*; + +public class SB_1939 { + static int N,M, start, end; + static List> adj = new ArrayList<>(); + static int[] dist; + + private static int dijskra() { + PriorityQueue pq = new PriorityQueue<>(); + pq.offer(new Node(start, Integer.MAX_VALUE)); // 최소값(최소값 중 최대)을 찾는것이기 때문에 맥스값으로 시작 + dist[start] = Integer.MAX_VALUE; + + while (!pq.isEmpty()) { + Node cur = pq.poll(); + if (cur.idx==end) return cur.c; // 도착점 도달 시 최대 중량 반환 + + if (cur.c < dist[cur.idx]) continue; + for (Node nxt : adj.get(cur.idx)) { + int weight = Math.min(cur.c, nxt.c); // 현재까지 중량과 다음 간선의 중량 중 최소값 + if (dist[nxt.idx] < weight) { + dist[nxt.idx] = weight; + pq.offer(new Node(nxt.idx, weight)); + } + } + } + return 0; // 도달할 수 없는 경우 + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + + dist = new int[N+1]; + Arrays.fill(dist, -1); + for (int i = 0; i <= N; i++) { + adj.add(new ArrayList<>()); + } + + for (int i = 0; i < M; i++) { + st = new StringTokenizer(br.readLine()); + int a = Integer.parseInt(st.nextToken()); + int b = Integer.parseInt(st.nextToken()); + int c = Integer.parseInt(st.nextToken()); + adj.get(a).add(new Node(b, c)); + adj.get(b).add(new Node(a, c)); + } + st = new StringTokenizer(br.readLine()); + start = Integer.parseInt(st.nextToken()); + end = Integer.parseInt(st.nextToken()); + + System.out.println(dijskra()); + } + + private static class Node implements Comparable{ + int idx, c; + + public Node(int u, int c) { + this.idx = u; + this.c = c; + } + + @Override + public int compareTo(Node o) { + return o.c - this.c; + } + } +} diff --git "a/BOJ/1000-5000\353\262\210/SB_2151.java" "b/BOJ/1000-5000\353\262\210/SB_2151.java" new file mode 100644 index 00000000..c46b1b3b --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/SB_2151.java" @@ -0,0 +1,93 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Arrays; +import java.util.PriorityQueue; + +public class SB_2151 { + static int N; + static char[][] board; + static Node start; + static int[][] visited; + static PriorityQueue pq = new PriorityQueue<>(); + static int[] dx = {-1, 0, 1, 0}; + static int[] dy = {0, 1, 0, -1}; + + private static int bfs() { + visited[start.x][start.y] = 0; + board[start.x][start.y] = '*'; + + while (!pq.isEmpty()) { + Node cur = pq.poll(); + + if (board[cur.x][cur.y]=='#') return cur.cnt; + + int nx = cur.x + dx[cur.d]; + int ny = cur.y + dy[cur.d]; + + if (!isValid(nx, ny) || board[nx][ny] == '*') continue; + if (visited[nx][ny] >= cur.cnt) continue; + + visited[nx][ny] = cur.cnt; + pq.offer(new Node(nx, ny, cur.d, cur.cnt)); + + if (board[nx][ny] == '!') { + pq.offer(new Node(nx, ny, (cur.d + 1) % 4, cur.cnt + 1)); + pq.offer(new Node(nx, ny, (cur.d + 3) % 4, cur.cnt + 1)); + } + } + return -1; + } + + private static boolean isValid(int x, int y) { + return 0 <= x && x < N && 0 <= y && y < N; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + N = Integer.parseInt(br.readLine()); + + board = new char[N][N]; + visited = new int[N][N]; + + for (int i = 0; i < N; i++) { + String line = br.readLine(); + for (int j = 0; j < N; j++) { + board[i][j] = line.charAt(j); + if (board[i][j] == '#') { + start = new Node(i, j, 0, 0); + } + } + } + + for (int i = 0; i < N; i++) { + Arrays.fill(visited[i], -1); + } + + for (int i = 0; i < 4; i++) { + int nx = start.x + dx[i]; + int ny = start.y + dy[i]; + + if (!isValid(nx, ny) || board[nx][ny] == '*') continue; + pq.offer(new Node(start.x, start.y, i, 0)); + } + + System.out.println(bfs()); + } + + static class Node implements Comparable { + int x, y, d, cnt; + + public Node(int x, int y, int d, int cnt) { + this.x = x; + this.y = y; + this.d = d; + this.cnt = cnt; + } + + @Override + public int compareTo(Node o) { + return this.cnt - o.cnt; + } + } +} diff --git "a/BOJ/1000-5000\353\262\210/SB_2169.java" "b/BOJ/1000-5000\353\262\210/SB_2169.java" new file mode 100644 index 00000000..0d77ffe0 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/SB_2169.java" @@ -0,0 +1,55 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +public class SB_2169 { + static int N, M; + static int[][] board; + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + + board = new int[N][M]; + for (int i = 0; i < N; i++) { + st = new StringTokenizer(br.readLine()); + for (int j = 0; j < M; j++) { + board[i][j] = Integer.parseInt(st.nextToken()); + } + } + + int[][] dp = new int[N][M]; + + // 첫번째 행 초기화 + dp[0][0] = board[0][0]; + for (int j = 1; j < M; j++) { // 오른쪽으로만 탐색 가능(이미 지나온 길 탐색 불가) + dp[0][j] = board[0][j] + dp[0][j - 1]; + } + + for (int i = 1; i < N; i++) { + int[] left = new int[M]; + int[] right = new int[M]; + + left[0] = dp[i - 1][0] + board[i][0]; // 0번째열은 일단 이전 행에서 아래로 내려와야함 (위에서 내려오는 한가지 경우) + for (int j = 1; j < M; j++) { // 왼쪽에서 오는거, 위에서 내려오는 두가지 경우 + left[j] = Math.max(left[j - 1], dp[i - 1][j]) + board[i][j]; + } + + right[M-1] = dp[i- 1][M-1] + board[i][M-1]; + for (int j = M - 2; j >= 0; j--) { + right[j] = Math.max(right[j+1], dp[i-1][j]) + board[i][j]; + } + + // 왼쪽 오른쪽 값 합침 + for (int j = 0; j < M; j++) { + dp[i][j] = Math.max(left[j], right[j]); + } + } + + System.out.println(dp[N-1][M-1]); + } +} diff --git "a/BOJ/1000-5000\353\262\210/SB_2170.java" "b/BOJ/1000-5000\353\262\210/SB_2170.java" new file mode 100644 index 00000000..742feea5 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/SB_2170.java" @@ -0,0 +1,56 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.PriorityQueue; +import java.util.StringTokenizer; + +public class SB_2170 { + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st; + + PriorityQueue pq = new PriorityQueue<>(); + + int N = Integer.parseInt(br.readLine()); + for (int i = 0; i < N; i++) { + st = new StringTokenizer(br.readLine()); + int s = Integer.parseInt(st.nextToken()); + int e = Integer.parseInt(st.nextToken()); + pq.offer(new Node(s, e)); + } + + Node first = pq.poll(); + int start = first.s; + int end = first.e; + int cnt = 0; + + while (!pq.isEmpty()) { + Node cur = pq.poll(); + if (start <= cur.s && cur.s <= end) { // 현재 선분이랑 겹칠 경우 + end = Math.max(end, cur.e); // 더 큰 끝값으로 업데이트 + continue; + } + + // 겹치지 않음 (== 새로운 선분 시작) + cnt += end - start; // 지금까지의 선분 길이 더해주기 + start = cur.s; + end = cur.e; + } + cnt += end-start; // 마지막 선분 길이 업데이트 + + System.out.println(cnt); + } + static class Node implements Comparable{ + int s, e; + + public Node(int s, int e) { + this.s = s; + this.e = e; + } + + @Override + public int compareTo(Node o) { + return this.s - o.s; + } + } +} diff --git "a/BOJ/1000-5000\353\262\210/SB_2504.java" "b/BOJ/1000-5000\353\262\210/SB_2504.java" new file mode 100644 index 00000000..fd100f82 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/SB_2504.java" @@ -0,0 +1,52 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayDeque; +import java.util.Deque; + +public class SB_2504 { + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + String line = br.readLine(); + + Deque stack = new ArrayDeque<>(); + int ans = 0; + int tmp = 1; + + for (int i = 0; i < line.length(); i++) { + char cur = line.charAt(i); + switch (cur) { + case '(': + stack.addFirst(cur); + tmp*=2; + break; + case '[': + stack.addFirst(cur); + tmp*=3; + break; + case ')': + if (stack.isEmpty() || stack.peekFirst() != '('){ + System.out.println(0); + return; + } + if (line.charAt(i - 1) == '(') ans+=tmp; + tmp/=2; + stack.pollFirst(); + break; + case ']': + if (stack.isEmpty() || stack.peekFirst() != '['){ + System.out.println(0); + return; + } + if (line.charAt(i-1)=='[') ans+=tmp; + tmp/=3; + stack.pollFirst(); + break; + } + } + + // 남아있는 괄호 여부 체크 + if (stack.isEmpty()) System.out.println(ans); + else System.out.println(0); + } +} diff --git "a/BOJ/1000-5000\353\262\210/SB_2629.java" "b/BOJ/1000-5000\353\262\210/SB_2629.java" new file mode 100644 index 00000000..9ae452ae --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/SB_2629.java" @@ -0,0 +1,44 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +public class SB_2629 { + static int N; + static int[] weight; + static boolean[][] dp; + + private static void recursive(int idx, int w) { + if (idx > N || dp[idx][w]) return; + dp[idx][w] = true; + recursive(idx + 1, w + weight[idx]); // 새로운 추를 기존 무게와 더할 경우 + recursive(idx + 1, Math.abs(w - weight[idx])); // 새로운 추를 기존 무게와 뺄 경우 + recursive(idx + 1, w); // 새로운 추를 선택하지 않을 경우 + } + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st; + StringBuilder sb = new StringBuilder(); + + N = Integer.parseInt(br.readLine()); + int mx = N * 500; // 주어진 구슬로 확인 가능한 최대 무게 + weight = new int[N+1]; + dp = new boolean[N + 1][(N * 500) + 1]; + + st = new StringTokenizer(br.readLine()); + for (int i = 0; i < N; i++) { + weight[i] = Integer.parseInt(st.nextToken()); + } + + recursive(0, 0); + + int M = Integer.parseInt(br.readLine()); + st = new StringTokenizer(br.readLine()); + for (int i = 0; i < M; i++) { + int mv = Integer.parseInt(st.nextToken()); + if (mv > mx || !dp[N][mv]) sb.append("N").append(" "); + else sb.append("Y").append(" "); + } + System.out.println(sb); + } +} diff --git "a/BOJ/1000-5000\353\262\210/SB_3151.java" "b/BOJ/1000-5000\353\262\210/SB_3151.java" new file mode 100644 index 00000000..8de73e49 --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/SB_3151.java" @@ -0,0 +1,57 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Arrays; +import java.util.StringTokenizer; + +public class SB_3151 { + static int N; + static int[] arr; + + private static int lowerBound(int start, int target) { + int s = start; + int e = N; + while (s < e) { + int mid = (s+e) / 2; + if (arr[mid] < target) s= mid+1; + else e = mid; + } + return s; + } + + private static int upperBound(int start, int target) { + int s = start; + int e = N; + while (s < e) { + int mid = (s + e) / 2; + if (arr[mid] <= target ) s=mid+1; + else e = mid; + } + return s; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st; + + N = Integer.parseInt(br.readLine()); + arr = new int[N]; + + st = new StringTokenizer(br.readLine()); + for (int i = 0; i < N; i++) { + arr[i] = Integer.parseInt(st.nextToken()); + } + + Arrays.sort(arr); + + long cnt = 0; + for (int i = 0; i < N; i++) { + for (int j = i + 1; j < N; j++) { + int left = lowerBound(j + 1, (arr[i] + arr[j]) * -1); + int right = upperBound(j + 1, (arr[i] + arr[j]) * -1); + cnt += right-left; + } + } + System.out.println(cnt); + } +} diff --git "a/BOJ/10001-15000\353\262\210/JM_12784.java" "b/BOJ/10001-15000\353\262\210/JM_12784.java" new file mode 100644 index 00000000..f6796e8a --- /dev/null +++ "b/BOJ/10001-15000\353\262\210/JM_12784.java" @@ -0,0 +1,66 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.StringTokenizer; + +/** + * 22%에서 틀림 -> N = 1일 때 고려해주기 + */ +public class JM_12784 { + static class Node { + int node; + int dynamite; + + public Node(int node, int dynamite) { + this.node = node; + this.dynamite = dynamite; + } + } + static int N; + static int M; + static ArrayList[] graph; + static final int INF = 987654321; + + private static int dfs(int curr, boolean[] visited) { + visited[curr] = true; + + int minD = 0; + for(Node next: graph[curr]) { + if (visited[next.node]) continue; + minD += Math.min(next.dynamite, dfs(next.node, visited)); + } + return (minD == 0) ? INF : minD; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + int T = Integer.parseInt(st.nextToken()); + + StringBuilder sb = new StringBuilder(); + while (T-- > 0) { + st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + + graph = new ArrayList[N + 1]; + for (int i = 0; i <= N; i++) { + graph[i] = new ArrayList<>(); + } + + for (int i = 0; i < M; i++) { + st = new StringTokenizer(br.readLine()); + int u = Integer.parseInt(st.nextToken()); + int v = Integer.parseInt(st.nextToken()); + int d = Integer.parseInt(st.nextToken()); + graph[u].add(new Node(v, d)); + graph[v].add(new Node(u, d)); + } + + if(N == 1) sb.append("0").append("\n"); + else sb.append(dfs(1, new boolean[N + 1])).append("\n"); + } + System.out.println(sb); + } +} diff --git "a/BOJ/10001-15000\353\262\210/JM_14852.java" "b/BOJ/10001-15000\353\262\210/JM_14852.java" new file mode 100644 index 00000000..49f58925 --- /dev/null +++ "b/BOJ/10001-15000\353\262\210/JM_14852.java" @@ -0,0 +1,35 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +public class JM_14852 { + static int N; + static final int MOD = 1_000_000_007; + + private static long solve() { + if(N == 1) return 2; + else if(N == 2) return 7; + + long[] dp = new long[N + 1]; + long[] sum = new long[N + 1]; + + dp[1] = 2; + dp[2] = 7; + sum[2] = 1; + + for (int i = 3; i <= N; i++) { + sum[i] = (dp[i - 3] + sum[i - 1]) % MOD; + dp[i] = (2 * dp[i - 1] + 3 * dp[i - 2] + 2 * sum[i]) % MOD; + } + + return dp[N]; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + System.out.println(solve()); + } +} diff --git "a/BOJ/10001-15000\353\262\210/JM_16724.java" "b/BOJ/10001-15000\353\262\210/JM_16724.java" new file mode 100644 index 00000000..e8592946 --- /dev/null +++ "b/BOJ/10001-15000\353\262\210/JM_16724.java" @@ -0,0 +1,61 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +public class JM_16724 { + static int N; + static int M; + static final int[][] DIR = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; + static int[][] map; + static int cycle; + + private static void dfs(int y, int x, boolean[][] visited, boolean[][] finished) { + visited[y][x] = true; + + int ny = y + DIR[map[y][x]][0]; + int nx = x + DIR[map[y][x]][1]; + + if(!visited[ny][nx]) dfs(ny, nx, visited, finished); + else if(!finished[ny][nx]) cycle++; + + finished[y][x] = true; + } + + private static int solve() { + cycle = 0; + boolean[][] visited = new boolean[N][M]; + boolean[][] finished = new boolean[N][M]; + for (int i = 0; i < N; i++) { + for (int j = 0; j < M; j++) { + if (visited[i][j]) + continue; + dfs(i, j, visited, finished); + } + } + return cycle; + } + + private static int getDir(char dir) { + if(dir == 'U') return 0; + else if(dir == 'D') return 1; + else if(dir == 'L') return 2; + return 3; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + map = new int[N][M]; + + for (int i = 0; i < N; i++) { + char[] tmp = br.readLine().toCharArray(); + for (int j = 0; j < M; j++) { + map[i][j] = getDir(tmp[j]); + } + } + System.out.println(solve()); + } +} diff --git "a/BOJ/10001-15000\353\262\210/JM_18430.java" "b/BOJ/10001-15000\353\262\210/JM_18430.java" new file mode 100644 index 00000000..6b633700 --- /dev/null +++ "b/BOJ/10001-15000\353\262\210/JM_18430.java" @@ -0,0 +1,75 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +public class JM_18430 { + static int N; + static int M; + static int[][] tree; + static int answer; + static final int[][][] boomerang = { + {{0, -1}, {1, 0}}, + {{-1, 0}, {0, -1}}, + {{-1, 0}, {0, 1}}, + {{0, 1}, {1, 0}} + }; + + private static boolean inRange(int y, int x) { + return 0 <= y && y < N && 0 <= x && x < M; + } + + private static void solve(int index, int totalSum, boolean[][] check) { + if(index == N * M) { + answer = Math.max(answer, totalSum); + return; + } + + int y = index / M; + int x = index % M; + + if(check[y][x]) { + solve(index + 1, totalSum, check); + return; + } + + check[y][x] = true; + for (int i = 0; i < 4; i++) { + int y1 = y + boomerang[i][0][0]; + int x1 = x + boomerang[i][0][1]; + int y2 = y + boomerang[i][1][0]; + int x2 = x + boomerang[i][1][1]; + + if(!inRange(y1, x1) || !inRange(y2, x2)) continue; + if(check[y1][x1] || check[y2][x2]) continue; + + check[y1][x1] = true; + check[y2][x2] = true; + int currSum = tree[y][x] * 2 + tree[y1][x1] + tree[y2][x2]; + solve(index + 1, totalSum + currSum, check); + check[y1][x1] = false; + check[y2][x2] = false; + } + check[y][x] = false; + + solve(index + 1, totalSum, check); + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + + tree = new int[N][M]; + for (int i = 0; i < N; i++) { + st = new StringTokenizer(br.readLine()); + for (int j = 0; j < M; j++) { + tree[i][j] = Integer.parseInt(st.nextToken()); + } + } + + solve(0, 0, new boolean[N][M]); + System.out.println(answer); + } +} diff --git "a/BOJ/10001-15000\353\262\210/JM_19237.java" "b/BOJ/10001-15000\353\262\210/JM_19237.java" new file mode 100644 index 00000000..0980ed58 --- /dev/null +++ "b/BOJ/10001-15000\353\262\210/JM_19237.java" @@ -0,0 +1,179 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.PriorityQueue; +import java.util.StringTokenizer; + +/** + * 25% 틀림 -> 1000초 이상 아니고, 초과로 + */ +public class JM_19237 { + static class Smell { + int sn; + int k; + + public Smell(int sn, int k) { + this.sn = sn; + this.k = k; + } + + public void set(int sn, int k) { + this.sn = sn; + this.k = k; + } + + @Override + public String toString() { + return "(" + sn + ", " + k + ')'; + } + } + static class Shark implements Comparable { + int sn; + int y, x; + int d; + + public Shark(int sn, int y, int x, int d) { + this.y = y; + this.x = x; + this.sn = sn; + this.d = d; + } + + @Override + public int compareTo(Shark o) { + return this.sn - o.sn; + } + + @Override + public String toString() { + return "Shark{" + + "sn=" + sn + + ", y=" + y + + ", x=" + x + + ", d=" + d + + '}'; + } + } + static int N; // 격자 NxN + static int M; // 상어 개수 + static int K; // 냄새 사라지는 시간 + static Smell[][] map; + static int[][][] sharkPriorityDir; + static PriorityQueue sharks; + static PriorityQueue nextShanks; + static final int MAX_TIME = 1000; + static final int[][] DIR = {{0, 0}, {-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // 상,하,좌,우 + + private static boolean inRange(int y, int x) { + return 0 <= y && y < N && 0 <= x && x < N; + } + + private static void reduceKAll() { + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + if(map[i][j].sn == 0) continue; + map[i][j].k--; + if(map[i][j].k == 0) map[i][j].sn = 0; + } + } + } + + private static void move() { + while (!nextShanks.isEmpty()) { + Shark shank = nextShanks.poll(); + if(map[shank.y][shank.x].sn == 0 || map[shank.y][shank.x].sn == shank.sn) { + map[shank.y][shank.x].set(shank.sn, K + 1); // K + 1로 초기화 필요 + sharks.add(shank); + } + } + } + + private static void addNextShark() { + while (!sharks.isEmpty()) { + Shark curr = sharks.poll(); + Shark prev = null; // 가능한 이동 경로가 없을 경우, 냄새가 있는 칸 + Shark next = null; + + for(int nd : sharkPriorityDir[curr.sn][curr.d]) { + if(nd == 0) continue; + int ny = curr.y + DIR[nd][0]; + int nx = curr.x + DIR[nd][1]; + if(!inRange(ny,nx)) continue; + + if(next == null && map[ny][nx].sn == 0) { + next = new Shark(curr.sn, ny, nx, nd); + } + if(prev == null && map[ny][nx].sn == curr.sn) { + prev = new Shark(curr.sn, ny, nx, nd); + } + } + if(next == null) nextShanks.add(prev); + else nextShanks.add(next); + } + } + + private static int solve() { + int time = 0; + while (true) { + addNextShark(); // 1. 우선순위 방향 결정 + move(); // 2. 이동 + reduceKAll(); // 3. 현재 k 시간 감소시키기 + + time++; + if(time > MAX_TIME) return -1; + if(sharks.size() == 1) break; + } + return time; + } + + public static void init(int[][] tmpMap, int[] startDir) { + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + map[i][j] = new Smell(0, 0); + if(tmpMap[i][j] != 0) { + int n = tmpMap[i][j]; + map[i][j].set(n, K); + sharks.add(new Shark(tmpMap[i][j], i, j, startDir[n])); + } + } + } + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + K = Integer.parseInt(st.nextToken()); + map = new Smell[N][N]; + sharks = new PriorityQueue<>(); + nextShanks = new PriorityQueue<>(); + + int[][] tmpMap = new int[N][N]; + for (int i = 0; i < N; i++) { + st = new StringTokenizer(br.readLine()); + for (int j = 0; j < N; j++) { + tmpMap[i][j] = Integer.parseInt(st.nextToken()); + } + } + + int[] startDir = new int[M + 1]; + st = new StringTokenizer(br.readLine()); + for (int i = 1; i <= M; i++) { + startDir[i] = Integer.parseInt(st.nextToken()); + } + + sharkPriorityDir = new int[M + 1][5][5]; + for (int m = 1; m <= M; m++) { + for (int i = 1; i <= 4; i++) { + st = new StringTokenizer(br.readLine()); + for (int j = 1; j <= 4; j++) { + sharkPriorityDir[m][i][j] = Integer.parseInt(st.nextToken()); + } + } + } + + init(tmpMap, startDir); + System.out.println(solve()); + } +} diff --git "a/BOJ/10001-15000\353\262\210/JW_12784.java" "b/BOJ/10001-15000\353\262\210/JW_12784.java" new file mode 100644 index 00000000..828222e9 --- /dev/null +++ "b/BOJ/10001-15000\353\262\210/JW_12784.java" @@ -0,0 +1,55 @@ +import java.util.ArrayList; + +public class JW_12784 { + + static final int INF = Integer.MAX_VALUE; + + static ArrayList> graph; + static boolean[] visited; + + public static void main(String[] args) throws Exception { + int t = read(); + StringBuilder sb = new StringBuilder(); + while (t-- > 0) { + int n = read(), m = read(); + if(n == 1) { + sb.append(0).append("\n"); + continue; + } + graph = new ArrayList<>(); + for (int i = 0; i < n + 1; i++) + graph.add(new ArrayList<>()); + visited = new boolean[n + 1]; + int u, v, d; + for (int i = 0; i < m; i++) { + u = read(); + v = read(); + d = read(); + graph.get(u).add(new int[] { v, d }); + graph.get(v).add(new int[] { u, d }); + } + sb.append(recursive(new int[] { 1, INF })).append("\n"); + } + System.out.println(sb); + } + + private static int recursive(int[] u) { + visited[u[0]] = true; + int minD = 0; + // 자식이 가지는 모든 값 + for (int[] v : graph.get(u[0])) + if (!visited[v[0]]) + minD += recursive(v); + // 현재 섬으로 오는 가중치와 자식으로 가는 간선 가중치의 합을 비교 + return Math.min(minD == 0 ? INF : minD, u[1]); // 갱신되지 않았을 경우 INF 반환 + } + + private static int read() throws Exception { + int c, n = System.in.read() & 15; + while ((c = System.in.read()) >= 48) + n = (n << 3) + (n << 1) + (c & 15); + if (c == 13) + System.in.read(); + return n; + } +} diff --git "a/BOJ/10001-15000\353\262\210/JW_14852.java" "b/BOJ/10001-15000\353\262\210/JW_14852.java" new file mode 100644 index 00000000..d7cda152 --- /dev/null +++ "b/BOJ/10001-15000\353\262\210/JW_14852.java" @@ -0,0 +1,31 @@ +import java.util.Arrays; +import java.util.PriorityQueue; + +public class JW_14852 { + static long dp[]; + static final int MOD = 1_000_000_007; + + public static void main(String[] args) throws Exception { + int n = read(); + dp = new long[n + 1]; + dp[0] = 1; + dp[1] = 2; + if (n > 1) + dp[2] = 7; + long temp = 20; + for (int i = 3; i <= n; i++) { + dp[i] = (temp + dp[i - 2]) % MOD; + temp = (temp + dp[i] * 2) % MOD; + } + System.out.println(dp[n]); + } + + private static int read() throws Exception { + int c, n = System.in.read() & 15; + while ((c = System.in.read()) >= 48) + n = (n << 3) + (n << 1) + (c & 15); + if (c == 13) + System.in.read(); + return n; + } +} diff --git "a/BOJ/10001-15000\353\262\210/JY_12784.java" "b/BOJ/10001-15000\353\262\210/JY_12784.java" new file mode 100644 index 00000000..b21b2765 --- /dev/null +++ "b/BOJ/10001-15000\353\262\210/JY_12784.java" @@ -0,0 +1,71 @@ +import java.io.*; +import java.util.*; +public class JY_12784 { + + static int N, M; + static List[] g; + static boolean[] visited; + static class Node { + int num, cost; + public Node(int num, int cost) { + this.num = num; + this.cost = cost; + } + @Override + public String toString() { + return "Node [num=" + num + ", cost=" + cost + "]"; + } + + + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + int T = Integer.parseInt(st.nextToken()); + StringBuilder sb = new StringBuilder(); + for(int t=0; t(); + } + + for(int i=0; i 자식 순회 + int minCost = 0; + for(Node next: g[now]) { + if(visited[next.num]) continue; + minCost += Math.min(next.cost, dfs(next.num)); + } + + return minCost; + } + +} \ No newline at end of file diff --git "a/BOJ/10001-15000\353\262\210/JY_14852.java" "b/BOJ/10001-15000\353\262\210/JY_14852.java" new file mode 100644 index 00000000..54a577b6 --- /dev/null +++ "b/BOJ/10001-15000\353\262\210/JY_14852.java" @@ -0,0 +1,24 @@ +import java.io.*; + +public class JY_14852 { + static final int INF = 1_000_000_007; + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + int N = Integer.parseInt(br.readLine()); + + + long[] dp = new long[N + 1]; + dp[0] = 1; + dp[1] = 2; + + long sum = dp[0] + dp[1]; + + for (int i = 2; i <= N; i++) { + dp[i] = (2 * sum + dp[i - 2]) % INF; + sum = (sum + dp[i]) % INF; + } + + System.out.println(dp[N]); + } +} diff --git "a/BOJ/10001-15000\353\262\210/SB_12784.java" "b/BOJ/10001-15000\353\262\210/SB_12784.java" new file mode 100644 index 00000000..457cd877 --- /dev/null +++ "b/BOJ/10001-15000\353\262\210/SB_12784.java" @@ -0,0 +1,67 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +public class SB_12784 { + static List> adj; + static boolean[] parents; + + private static int dfs(int node) { + int cnt = 0; + parents[node] = true; + + for (Node nxt : adj.get(node)) { + if (parents[nxt.idx]) continue; // 부모는 패쓰 + cnt += Math.min(nxt.val, dfs(nxt.idx)); + } + + if (cnt==0 && adj.get(node).size()==1) return adj.get(node).get(0).val; // 리프노드면 부모와 이어진 값 반환 + return cnt; + } + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st; + StringBuilder sb = new StringBuilder(); + + int T = Integer.parseInt(br.readLine()); + while (T-- > 0) { + st = new StringTokenizer(br.readLine()); + int N = Integer.parseInt(st.nextToken()); + int M = Integer.parseInt(st.nextToken()); + if (N==1) { + sb.append(0).append("\n"); + continue; + } + adj = new ArrayList<>(); + for (int i = 0; i <= N; i++) { + adj.add(new ArrayList<>()); + } + parents = new boolean[N + 1]; + for (int i = 0; i < M; i++) { + st = new StringTokenizer(br.readLine()); + int u = Integer.parseInt(st.nextToken()); + int v = Integer.parseInt(st.nextToken()); + int c = Integer.parseInt(st.nextToken()); + adj.get(u).add(new Node(v, c)); + adj.get(v).add(new Node(u, c)); + } + sb.append(dfs(1)).append("\n"); + } + + // 1과 연결된 부모 노드 구하기 (재귀) + // 해당 노드와 연결된 리프노드들에서 해당 노드로 오는 값의 합, 해당 노드에서 부모노드까지 합 중 최소값 선택 + System.out.println(sb); + } + + private static class Node{ + int idx, val; + + public Node(int idx, int val) { + this.idx = idx; + this.val = val; + } + } +} diff --git "a/BOJ/10001-15000\353\262\210/SB_14852.java" "b/BOJ/10001-15000\353\262\210/SB_14852.java" new file mode 100644 index 00000000..592a9c9e --- /dev/null +++ "b/BOJ/10001-15000\353\262\210/SB_14852.java" @@ -0,0 +1,33 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +public class SB_14852 { + static int MOD = 1_000_000_007; + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + int N = Integer.parseInt(br.readLine()); + + if (N==1) { + System.out.println(2); + return; + } + if (N==2) { + System.out.println(7); + return; + } + + long[] dp = new long[N + 1]; + + dp[1] = 2; + dp[2] = 7; + + long sum = 2; + + for (int i = 3; i <= N; i++) { + dp[i] = (2 * dp[i - 1] + 3 * dp[i - 2] + sum) % MOD; + sum += dp[i - 2] * 2 % MOD; + } + System.out.println(dp[N]); + } +} diff --git "a/BOJ/15001-20000\353\262\210/JW_16724.java" "b/BOJ/15001-20000\353\262\210/JW_16724.java" new file mode 100644 index 00000000..89a65cb3 --- /dev/null +++ "b/BOJ/15001-20000\353\262\210/JW_16724.java" @@ -0,0 +1,57 @@ +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +public class JW_16724 { + + static int n, m, cnt = 0; + static int[] board; + static boolean[] visited, isCycle; + + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + n = Integer.parseInt(st.nextToken()); + m = Integer.parseInt(st.nextToken()); + // 행, 열을 인덱스화 + board = new int[n * m]; + visited = new boolean[n * m]; + isCycle = new boolean[n * m]; + for (int i = 0; i < n; i++) { + char[] line = br.readLine().toCharArray(); + for (int j = 0; j < m; j++) + // 다음 인덱스 계산을 편하게 하기 위해 변화량으로 변환 + switch (line[j]) { + case 'U': + board[i * m + j] = -m; + break; + case 'D': + board[i * m + j] = m; + break; + case 'L': + board[i * m + j] = -1; + break; + case 'R': + board[i * m + j] = +1; + break; + } + } + // 사이클 검출 + for (int i = 0; i < n * m; i++) + if (!visited[i]) { + dfs(i); + } + System.out.println(cnt); + } + + private static void dfs(int cur) { + // 방문하지 않은 인덱스라면 + if (!visited[cur]) { + visited[cur] = true; + dfs(cur + board[cur];); // 다음 재귀 호출 + // 방문했다면 사이클 발생 + } else if (!isCycle[cur]) + cnt++; + isCycle[cur] = true; + } +} \ No newline at end of file diff --git "a/BOJ/15001-20000\353\262\210/JW_18430.java" "b/BOJ/15001-20000\353\262\210/JW_18430.java" new file mode 100644 index 00000000..32ae5c7b --- /dev/null +++ "b/BOJ/15001-20000\353\262\210/JW_18430.java" @@ -0,0 +1,63 @@ +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +public class JW_18430 { + + static int n, m, maxValue = 0; + static int[] board; + static int[] dir + + public static void main(String[] args) throws Exception { + n = read(); + m = read(); + dir = new int[] { -m, 1, m, -1 }; // 방향 증감 + board = new int[n * m]; + for (int i = 0; i < n * m; i++) + board[i] = read(); + recursive(0, 0, new boolean[n * m]); + System.out.println(maxValue); + } + + // 재귀로 부메랑 만들기 + private static void recursive(int cur, int sumValue, boolean[] visited) { + maxValue = Math.max(maxValue, sumValue); // 최댓값 갱신 + for (int i = cur; i < n * m; i++) { + // 사용되지 않은 재료 + if (!visited[i]) + for (int j = 0; j < 4; j++) { + int next1 = i + dir[j]; + int next2 = i + dir[(j + 1) % 4]; + // 사용이 가능하다면 + if (isPossible(i, next1, next2, visited)) { + visited[i] = visited[next1] = visited[next2] = true; // 사용 + int value = board[i] * 2 + board[next1] + board[next2]; // 부메랑의 강도 계산 + recursive(i + 1, sumValue + value, visited); // 다음 재귀 호출 + visited[i] = visited[next1] = visited[next2] = false; // 백 트래킹 + } + } + } + } + + private static boolean isPossible(int idx, int idx1, int idx2, boolean[] visited) { + return isValid(idx, idx1) && isValid(idx, idx2) && !visited[idx1] && !visited[idx2]; + } + + private static boolean isValid(int cur, int next) { + if (next < 0 || next >= n * m) + return false; + // 행의 차이가 하나 이하 + if (Math.abs(cur % m - next % m) > 1) + return false; + return true; + } + + private static int read() throws Exception { + int c, n = System.in.read() & 15; + while ((c = System.in.read()) >= 48) + n = (n << 3) + (n << 1) + (c & 15); + if (c == 13) + System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/BOJ/15001-20000\353\262\210/JW_18513.java" "b/BOJ/15001-20000\353\262\210/JW_18513.java" new file mode 100644 index 00000000..eaf74e27 --- /dev/null +++ "b/BOJ/15001-20000\353\262\210/JW_18513.java" @@ -0,0 +1,56 @@ +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.HashSet; + +public class JW_18513 { + + public static void main(String[] args) throws Exception { + int n = read(), k = read(); + Deque dq = new ArrayDeque<>(); + HashSet hs = new HashSet<>(); + for (int i = 0; i < n; i++) { + int p = read(); + dq.offer(new int[] { p, p }); + hs.add(p); + } + long answer = 0; + while (!dq.isEmpty()) { + int size = dq.size(); + while (size-- > 0) { + int[] cur = dq.poll(); + int next = cur[0] + 1; + if (!hs.contains(next)) { + dq.offer(new int[] { next, cur[1] }); + hs.add(next); + answer += Math.abs(next - cur[1]); + if (--k == 0) { + System.out.println(answer); + return; + } + } + next = cur[0] - 1; + if (!hs.contains(next)) { + dq.offer(new int[] { next, cur[1] }); + hs.add(next); + answer += Math.abs(next - cur[1]); + if (--k == 0) { + System.out.println(answer); + return; + } + } + } + } + } + + private static int read() throws Exception { + int c, n = System.in.read() & 15; + boolean m = n == 13; + if (m) + n = System.in.read() & 15; + while ((c = System.in.read()) >= 48) + n = (n << 3) + (n << 1) + (c & 15); + if (c == 13) + System.in.read(); + return m ? ~n + 1 : n; + } +} diff --git "a/BOJ/15001-20000\353\262\210/JW_19237.java" "b/BOJ/15001-20000\353\262\210/JW_19237.java" new file mode 100644 index 00000000..e4bc4253 --- /dev/null +++ "b/BOJ/15001-20000\353\262\210/JW_19237.java" @@ -0,0 +1,160 @@ +import java.util.ArrayDeque; +import java.util.Deque; + +public class JW_19237 { + + // 상어 객체 + static class Shark { + int num, idx, dir; // 상어의 번호, 인덱스, 방향 + int[][] priority; // 해당 상어의 위치에 따른 방향 우선 순위 + + Shark(int num, int idx, int dir, int[][] priority) { + this.num = num; + this.idx = idx; + this.dir = dir; + this.priority = priority; + } + + // 방향 우선 순위 반환 + int[] getPriority() { + return priority[dir]; + } + } + + static int n, m, k; + static int[] scentBoard, remainBoard, move; // 냄새, 남은 시간, 방향 벡터 + static boolean[] visited; + static Deque sharks = new ArrayDeque<>(); // 상어 큐 + static Deque scentDeque = new ArrayDeque<>(); // 냄새 큐 + + public static void main(String[] args) throws Exception { + n = read(); + m = read(); + k = read(); + move = new int[] { 0, -n, n, -1, 1 }; + scentBoard = new int[n * n]; + remainBoard = new int[n * n]; + visited = new boolean[n * n]; + + // 기본 정보 입력 + init(); + + int time = 0; + while (time <= 1000) { + int size = sharks.size(); + + // 1번 상어만 남았다면 종료 + if (size == 1) { + System.out.println(time); + return; + } + + visited = new boolean[n * n]; // 방문 배열 초기화 + // 상어를 작은 번호 순대로 꺼내서 탐색 + while (size-- > 0) { + Shark shark = sharks.poll(); + int num = shark.num, idx = shark.idx; + int nextDir = getNextDir(shark); // 다음 방향 결정 + int next = idx + move[nextDir]; // 이동 + + // 이미 도착해있는 상어가 있다면 + // 즉, 자신보다 작은 번호의 상어가 도착해있다면 쫓겨남 + if (visited[next]) + continue; + + visited[next] = true; + shark.idx = next; + shark.dir = nextDir; + sharks.offer(shark); // 상어 큐에 삽입 + scentDeque.offer(new int[] { next, num }); // 냄새 큐에 삽입 + } + removeScent(); // 냄새 카운트 감소 + putScent(); // 냄새 배열에 적용 + time++; + } + System.out.println(-1); + } + + // 기본 정보 입력 + private static void init() throws Exception { + int[] tempSharks = new int[m + 1]; + for (int i = 0; i < n * n; i++) { + int num = read(); + if (num != 0) { + tempSharks[num] = i; // 상어의 인덱스 저장 + scentBoard[i] = num; // 냄새 삽입 + remainBoard[i] = k; // 남은 시간 기록 + } + } + int[] tempDir = new int[m + 1]; + for (int i = 1; i < m + 1; i++) + tempDir[i] = read(); + + // 상어 객체 생성 및 큐에 삽입 + for (int i = 1; i < m + 1; i++) { + int idx = tempSharks[i], dir = tempDir[i]; + int[][] priority = new int[5][5]; // 우선 순위 입력 + for (int j = 1; j < 5; j++) + for (int k = 1; k < 5; k++) + priority[j][k] = read(); + Shark shark = new Shark(i, idx, dir, priority); + sharks.offer(shark); + } + } + + // 다음 방향 결정 + private static int getNextDir(Shark shark) { + int[] priority = shark.getPriority(); // 우선 순위에 따라 방향 결정 + int myScent = 0; + for (int i = 1; i < 5; i++) { + int dir = priority[i]; + int next = shark.idx + move[dir]; + if (isValid(shark.idx, next)) { + if (scentBoard[next] == 0) + return dir; + else if (scentBoard[next] == shark.num && myScent == 0) + myScent = dir; + } + } + return myScent; + } + + // 냄새 카운트 감소 + private static void removeScent() { + for (int i = 0; i < n * n; i++) + if (scentBoard[i] != 0 && --remainBoard[i] == 0) + scentBoard[i] = 0; + } + + // 냄새 큐에 있는 좌표에 냄새 삽입 + private static void putScent() { + while (!scentDeque.isEmpty()) { + int[] scent = scentDeque.poll(); + int idx = scent[0], num = scent[1]; + scentBoard[idx] = num; + remainBoard[idx] = k; + } + } + + // 인덱스 유효성 검사 + private static boolean isValid(int cur, int next) { + // 전체 인덱스를 벗어나는 경우 + if (next < 0 || next >= n * n) + return false; + // 좌, 우로 움직일 때, 같은 행에 있는지 확인 + int curRow = cur / n; + int nextRow = next / n; + if (Math.abs(cur - next) == 1 && curRow != nextRow) + return false; + return true; + } + + private static int read() throws Exception { + int c, n = System.in.read() & 15; + while ((c = System.in.read()) >= 48) + n = (n << 3) + (n << 1) + (c & 15); + if (c == 13) + System.in.read(); + return n; + } +} diff --git "a/BOJ/15001-20000\353\262\210/JY_16724.java" "b/BOJ/15001-20000\353\262\210/JY_16724.java" new file mode 100644 index 00000000..3cefe178 --- /dev/null +++ "b/BOJ/15001-20000\353\262\210/JY_16724.java" @@ -0,0 +1,75 @@ +import java.io.*; +import java.util.*; +public class JY_16724 { + + static int N, M; + static char[][] g; + static int[] parent; + // 상 하 좌 우 + static int[] dx = {-1, 1, 0, 0}; + static int[] dy = {0, 0, -1, 1}; + static Map cMap; + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + g = new char[N][M]; + + parent = new int[N*M]; + for(int i=0; i(); + cMap.put('U', 0); + cMap.put('D', 1); + cMap.put('L', 2); + cMap.put('R', 3); + + for(int i=0; i cSet = new HashSet<>(); + for(int i=0; i=0 && x=0 && y q = new LinkedList<>(); + Set visited = new HashSet<>(); + + for(int a: arr) { + q.add(new int[] {a, 0}); + visited.add(a); + } + + long total = 0; + int cnt = 0; + while(!q.isEmpty()) { + int[] now = q.poll(); + for(int i=0; i<2; i++) { + int nx = now[0] + dx[i]; + + if(visited.contains(nx)) continue; + + total += (now[1]+1); + visited.add(nx); + q.add(new int[] {nx, now[1]+1}); + cnt++; + + // K만큼 설치했으면 중단 + if(cnt == K) return total; + } + } + + return total; + } +} diff --git "a/BOJ/15001-20000\353\262\210/JY_19237.java" "b/BOJ/15001-20000\353\262\210/JY_19237.java" new file mode 100644 index 00000000..41b6c068 --- /dev/null +++ "b/BOJ/15001-20000\353\262\210/JY_19237.java" @@ -0,0 +1,191 @@ +import java.io.*; +import java.util.*; + +public class JY_19237 { + + static int N, M, K; + static int[][] g; + static int[][] t; + static int[][][] drr; + static Shark[] srr; + static int[][] visited; + // 상 하 좌 우 + static int[] dx = {0, -1, 1, 0, 0}; + static int[] dy = {0, 0, 0, -1, 1}; + static boolean[] isDied; + static class Shark { + int num, x, y, dir; + + public Shark(int num, int x, int y, int dir) { + super(); + this.num = num; + this.x = x; + this.y = y; + this.dir = dir; + } + + @Override + public String toString() { + return "Shark [num=" + num + ", x=" + x + ", y=" + y + ", dir=" + dir + "]"; + } + + } + + + public static void main(String[] args) throws IOException{ + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + K = Integer.parseInt(st.nextToken()); + + g = new int[N][N]; // 냄새카운트 + visited = new int[N][N]; // 상어 경로 + srr = new Shark[M+1]; + for(int i=0; i 1000) System.out.println(-1); + else System.out.println(time); + + } + // -------- print + public static void printG(int[][] a) { + for(int i=0; i=0 && x=0 && y 자신의 냄새가 있는 칸으로 결정 + if(nDir == -1) { + for(int d=1; d<5; d++) { + int dir = drr[i][now.dir][d]; + int nx = now.x + dx[dir]; + int ny = now.y + dy[dir]; + if(!inRange(nx, ny)) continue; + if(visited[nx][ny] != now.num) continue; + nDir = dir; + break; + } + } + + // 2) 가장 우선순위 높은 방향으로 상어이동 + now.x += dx[nDir]; + now.y += dy[nDir]; + now.dir = nDir; + + // 이동한 곳에 번호가 낮은 다른 상어가 있음 -> 쫒겨남 + if(t[now.x][now.y] != 0) { + isDied[i] = true; + } + else { + visited[now.x][now.y] = now.num; + t[now.x][now.y] = K; + } + + } + } + public static void spreadSmell() { + // 원본배열 냄새는 -1 + // 새로운 배열 냄새 반영 + for(int i=0; i 0) { + g[i][j]--; + } + if(t[i][j] > 0) { + g[i][j] = t[i][j]; + } + } + } + } + public static boolean checkShark() { + for(int i=2; i 순환 그래프의 개수 구하기 + */ + +public class SB_16724 { + static int N, M; + static int[][] board; + static int[] dx = {-1, 1, 0, 0}; // 행 이동 + static int[] dy = {0, 0, -1, 1}; // 열 이동 + static boolean[][] visited; + static boolean[][] finished; + static int cycle = 0; + + private static void dfs(int x, int y) { + visited[x][y] = true; + + // 다음 좌표 + int d = board[x][y]; + int nx = x+dx[d]; + int ny = y+dy[d]; + + if (visited[nx][ny] && !finished[nx][ny]) { // 사이클 찾은 경우 + cycle++; + } + + if (!visited[nx][ny]) dfs(nx, ny); // 방문안했을 경우 다음 좌표로 이동 + + finished[x][y] = true; // 현재 노드의 dfs를 다 돌았으면 끝났음 표시 + } + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + + board = new int[N][M]; + visited = new boolean[N][M]; + finished = new boolean[N][M]; + for (int i = 0; i < N; i++) { + String line = br.readLine(); + for (int j = 0; j < M; j++) { + char d = line.charAt(j); + switch (d){ + case 'U': + board[i][j] = 0; + break; + case 'D': + board[i][j] = 1; + break; + case 'L': + board[i][j] = 2; + break; + case 'R': + board[i][j] = 3; + break; + } + } + } + + for (int i = 0; i < N; i++) { + for (int j = 0; j < M; j++) { + if (!finished[i][j]) dfs(i, j); + } + } + + System.out.println(cycle); + } +} diff --git "a/BOJ/15001-20000\353\262\210/SB_18430.java" "b/BOJ/15001-20000\353\262\210/SB_18430.java" new file mode 100644 index 00000000..2993a63f --- /dev/null +++ "b/BOJ/15001-20000\353\262\210/SB_18430.java" @@ -0,0 +1,78 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +public class SB_18430 { + static int N,M; + static int[][] board; + static int[][] wings = { + {0, -1, 1, 0}, + {-1, 0, 0, -1}, + {-1, 0, 0, 1}, + {0, 1, 1, 0} + }; + static int ans = 0; + + private static void dfs(int x, int y, int val, boolean[][] visited) { + if(x==N) { // 모든 칸 탐색 + ans = Math.max(ans, val); + return; + } + + int nx = (y+1 == M) ? x+1 : x; // 다음 위치, 다음 행으로 이동 or 열로 이동 + int ny = (y+1 == M) ? 0 : y+1; + + if (visited[x][y]){ + dfs(nx, ny, val, visited); + return; + } + + visited[x][y] = true; + for (int[] w : wings){ + int lx = x + w[0]; // 날개 좌표 + int ly = y + w[1]; + int rx = x + w[2]; + int ry = y + w[3]; + + if (!isValid(lx, ly) || !isValid(rx, ry) || visited[lx][ly] || visited[rx][ry]) continue; + + visited[lx][ly] = true; + visited[rx][ry] = true; + + int curVal = val + board[x][y]*2 + board[lx][ly] + board[rx][ry]; + dfs(nx, ny, curVal, visited); + visited[lx][ly] = false; + visited[rx][ry] = false; + } + visited[x][y] = false; + + // 부메랑 안만드는 경우 + dfs(nx, ny, val, visited); + + } + + private static boolean isValid(int x, int y){ + return 0<=x && x que = new ArrayDeque<>(); + static HashSet set = new HashSet<>(); + static int[] dir = new int[]{-1, 1}; + + private static long bfs() { + long cnt = 0; + + int check = 0; + while (!que.isEmpty()) { + Node cur = que.poll(); + + for (int d : dir) { + int nxt = cur.i + d; + if (set.contains(nxt)) continue; + cnt+= cur.v+1; + set.add(nxt); + que.offer(new Node(nxt, cur.v + 1)); + check++; + + if (check==K) return cnt; + } + } + return cnt; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + K = Integer.parseInt(st.nextToken()); + + st = new StringTokenizer(br.readLine()); + for (int i = 0; i < N; i++) { + int idx = Integer.parseInt(st.nextToken()); + que.offer(new Node(idx, 0)); + set.add(idx); + } + + System.out.println(bfs()); + } +} + +class Node { + int i, v; + public Node(int i, int v) { + this.i = i; + this.v = v; + } +} diff --git "a/BOJ/15001-20000\353\262\210/SB_19237.java" "b/BOJ/15001-20000\353\262\210/SB_19237.java" new file mode 100644 index 00000000..c4b4ce1c --- /dev/null +++ "b/BOJ/15001-20000\353\262\210/SB_19237.java" @@ -0,0 +1,205 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.*; + +public class SB_19237 { + static int N, M, K; + static int[] dx = {-1, 1, 0, 0}; // 상하좌우 + static int[] dy = {0, 0, -1, 1}; + static int[][] board; + static Smell[][] sBoard; + static int[][][] dir; + static Shark[] sharks; + + private static boolean checkShark() { + int cnt = 0; + for (Shark s : sharks) { + if (!s.isDead) cnt++; + } + return cnt == 1; + } + + private static void spreadSmell() { + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + if (sBoard[i][j].idx==0) continue; + sBoard[i][j].t--; + if (sBoard[i][j].t==0) sBoard[i][j].idx = 0; + } + } + } + + private static void moveShark() { + int[][] tmpBoard = new int[N][N]; + + for (Shark s : sharks) { + if (s.idx==0 || s.isDead) continue; + + // 아무 냄새 없는 칸 있는지 체크 + int mvDir = -1; + for (int d : dir[s.idx][s.d]) { // 현재 상어가 보고있는 방향부터 + int nx = s.x + dx[d]; + int ny = s.y + dy[d]; + if (!isValid(nx, ny) || sBoard[nx][ny].idx!=0) continue; + mvDir = d; + break; + } + + if (mvDir==-1) { // 냄새 빈칸이 없을 경우 + for (int d : dir[s.idx][s.d]) { // 현재 상어가 바라보는 위치에서 이동 우선순위 + int nx = s.x + dx[d]; + int ny = s.y + dy[d]; + + if (!isValid(nx, ny) || sBoard[nx][ny].idx!= s.idx) continue; + mvDir = d; + break; + } + } + + // 위치 최종 설정 + s.x+= dx[mvDir]; + s.y += dy[mvDir]; + s.d = mvDir; + + if (tmpBoard[s.x][s.y] != 0) { + s.isDead = true; + }else{ + board[s.x][s.y] = s.idx; + tmpBoard[s.x][s.y] = K; + } + } + + + // 모든 상어가 이동이 끝나면 냄새 뿌리기 + for (Shark s : sharks) { + if (s.idx==0 || s.isDead) continue; + sBoard[s.x][s.y] = new Smell(s.idx, K); + } + } + + private static boolean isValid(int x, int y) { + return 0 <= x && x < N && 0 <= y && y < N; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + K = Integer.parseInt(st.nextToken()); + + board = new int[N][N]; + sBoard = new Smell[N][N]; + dir = new int[M+1][4][4]; + + // 냄새보드 초기화 + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + sBoard[i][j] = new Smell(0, 0); + } + } + + sharks = new Shark[M + 1]; + for (int i = 0; i < N; i++) { // 보드 입력 + st = new StringTokenizer(br.readLine()); + for (int j = 0; j < N; j++) { + int num = Integer.parseInt(st.nextToken()); + board[i][j] = num; + if (num != 0) { + sharks[num] = new Shark(num, i, j); + sBoard[i][j] = new Smell(num, K); // 처음 냄새 남기기 + } + } + } + + + st = new StringTokenizer(br.readLine()); // 상어 방향 입력 + for (int i = 1; i <= M; i++) { + int d = Integer.parseInt(st.nextToken())-1; + sharks[i].setDir(d); + } + sharks[0] = new Shark(0, 0, 0); + sharks[0].isDead = true; + + for (int k = 1; k <= M; k++) { // 상어별 우선순위 방향 입력 + for (int i=0; i<4; i++) { + st = new StringTokenizer(br.readLine()); + for (int j = 0; j < 4; j++) { + dir[k][i][j] = Integer.parseInt(st.nextToken())-1; + } + } + } + + int time = 0; + while (time++ <= 1000) { + // 상어 이동 + moveShark(); + + // 냄새 시간 -- + spreadSmell(); + + // 상어 체크 + if (checkShark()) { + System.out.println(time); + return; + } + } + System.out.println(-1); + } + + static class Shark implements Comparable{ + int x, y, idx, d; + boolean isDead = false; + + public Shark(int idx, int x, int y) { + this.idx = idx; + this.x = x; + this.y = y; + } + + public void setDir(int d) { + this.d = d; + } + + private void move(int x, int y, int d) { + this.x = x; + this.y = y; + this.d = d; + } + + @Override + public int compareTo(Shark o) { + return this.idx - o.idx; + } + + @Override + public String toString() { + return "Shark{" + + "x=" + x + + ", y=" + y + + ", idx=" + idx + + ", d=" + d + + ", isDead=" + isDead + + '}'; + } + } + + static class Smell{ + int idx, t; + + public Smell(int idx, int t) { + this.idx = idx; + this.t = t; + } + + @Override + public String toString() { + return "Smell{" + + "idx=" + idx + + ", t=" + t + + '}'; + } + } +} diff --git "a/BOJ/20001-25000\353\262\210/JM_21758.java" "b/BOJ/20001-25000\353\262\210/JM_21758.java" new file mode 100644 index 00000000..c008bddd --- /dev/null +++ "b/BOJ/20001-25000\353\262\210/JM_21758.java" @@ -0,0 +1,45 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +/** + * 꿀벌(0), 꿀벌(i), 벌통(N-1) + * 벌통(0), 꿀벌(i), 꿀벌(N-1) + * 꿀벌(0), 벌통(i), 꿀벌(N-1) + */ +public class JM_21758 { + static int N; + static int[] honey; + + private static long solve() { + int[] psum = new int[N]; + + psum[0] = honey[0]; + for (int i = 1; i < N; i++) { + psum[i] += psum[i - 1] + honey[i]; + } + + long maxSum = 0; + for (int i = 1; i < N - 1; i++) { + maxSum = Math.max(maxSum, (psum[N - 1] - honey[0] - honey[i]) + (psum[N - 1] - psum[i])); + maxSum = Math.max(maxSum, (psum[i - 1]) + (psum[N - 1] - honey[i] - honey[N - 1])); + maxSum = Math.max(maxSum, (psum[i] - honey[0]) + (psum[N - 1] - psum[i - 1] - honey[N - 1])); + } + return maxSum; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + honey = new int[N]; + + + st = new StringTokenizer(br.readLine()); + for (int i = 0; i < N; i++) { + honey[i] = Integer.parseInt(st.nextToken()); + } + System.out.println(solve()); + } +} diff --git "a/BOJ/20001-25000\353\262\210/JW_21578.java" "b/BOJ/20001-25000\353\262\210/JW_21578.java" new file mode 100644 index 00000000..e27563e6 --- /dev/null +++ "b/BOJ/20001-25000\353\262\210/JW_21578.java" @@ -0,0 +1,37 @@ +public class JW_21578 { + + public static void main(String[] args) throws Exception { + int n = read(); + int[] arr = new int[n], lSum = new int[n], rSum = new int[n]; + for (int i = 0; i < n; i++) + arr[i] = read(); + // 누적합 초기화 + lSum[0] = arr[0]; + rSum[n - 1] = arr[n - 1]; + for (int i = 1; i < n; i++) { + lSum[i] = lSum[i - 1] + arr[i]; // 왼쪽에서 오른쪽으로 누적합 + rSum[n - 1 - i] = rSum[n - i] + arr[n - 1 - i]; // 오른쪽에서 왼쪽으로 누적합 + } + int maxValue = 0; + for (int i = 0; i < n; i++) { + // 벌꿀벌 + maxValue = Math.max(maxValue, (lSum[i] + rSum[i] - lSum[0] - rSum[n - 1])); + if (i > 0) + // 벌벌꿀 + maxValue = Math.max(maxValue, (lSum[n - 1] - lSum[i]) * 2 + lSum[i - 1] - lSum[0]); + if (i < n - 1) + // 꿀벌벌 + maxValue = Math.max(maxValue, (rSum[0] - rSum[i]) * 2 + rSum[i + 1] - rSum[n - 1]); + } + System.out.println(maxValue); + } + + private static int read() throws Exception { + int c, n = System.in.read() & 15; + while ((c = System.in.read()) >= 48) + n = (n << 3) + (n << 1) + (c & 15); + if (c == 13) + System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/BOJ/20001-25000\353\262\210/JY_21758.java" "b/BOJ/20001-25000\353\262\210/JY_21758.java" new file mode 100644 index 00000000..2951fa78 --- /dev/null +++ "b/BOJ/20001-25000\353\262\210/JY_21758.java" @@ -0,0 +1,60 @@ +import java.io.*; +import java.util.*; +public class JY_21758 { + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + int N = Integer.parseInt(st.nextToken()); + int[] arr = new int[N]; + st = new StringTokenizer(br.readLine()); + for(int i=0; i=0; i--, j++) reArr[j] = arr[i]; + + // 오른쪽부터 누적합 + int[] preR = new int[N]; + preR[0] = reArr[0]; + for(int i=1; i 0 ? (R[rIdx] - dist) : 0; + int damage = punch / 2; + dfs(rIdx + 1, currH - damage, dist, surprise); + + + // 네발로 걷기 + int nextDist = dist + K; + damage = (R[rIdx] - nextDist) > 0 ? (R[rIdx] - nextDist) : 0; + dfs(rIdx + 1, currH - damage, nextDist, surprise); + + // 깜짝 놀라게 하기 + if(surprise && rIdx < N - 1) { + int tmpR = R[rIdx + 1]; + R[rIdx + 1] = 0; + dfs(rIdx + 1, currH - punch, dist, !surprise); + R[rIdx + 1] = tmpR; + } + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + + st = new StringTokenizer(br.readLine()); + H = Integer.parseInt(st.nextToken()); + D = Integer.parseInt(st.nextToken()); + K = Integer.parseInt(st.nextToken()); + + R = new int[N]; + for (int i = 0; i < N; i++) { + st = new StringTokenizer(br.readLine()); + R[i] = Integer.parseInt(st.nextToken()); + } + + dfs(0, H, D, true); + System.out.println(maxH <= 0 ? -1 : maxH); + } +} diff --git "a/BOJ/30000-35000\353\262\210/JM_32070.java" "b/BOJ/30000-35000\353\262\210/JM_32070.java" new file mode 100644 index 00000000..0819d599 --- /dev/null +++ "b/BOJ/30000-35000\353\262\210/JM_32070.java" @@ -0,0 +1,105 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +public class JM_32070 { + static class Color { + int box; + boolean up; + + public Color(int box, boolean up) { + this.box = box; + this.up = up; + } + } + static int N; + static Color[][] colors; + static int[] boxParent; + static int[] subBoxCount; + + private static int findParent(int x) { + if(x == boxParent[x]) return x; + return boxParent[x] = findParent(boxParent[x]); + } + + private static void union(int u, int v) { + int uP = findParent(u); + int vP = findParent(v); + if(uP < vP) { + boxParent[vP] = uP; + subBoxCount[uP] += subBoxCount[vP]; + } + else if(uP > vP) { + boxParent[uP] = vP; + subBoxCount[vP] += subBoxCount[uP]; + } + } + + private static void makeCycle() { + for (int i = 1; i <= N; i++) { + boxParent[i] = i; + subBoxCount[i] = 1; + } + + for (int i = 1; i <= N; i++) { // 같은 색의 공을 담은 box union + union(colors[i][0].box, colors[i][1].box); + } + } + + private static boolean isTwoPairsOnTop() { + int[] twoPairs = new int[N + 1]; + for (int i = 1; i <= N; i++) { + if(colors[i][0].up && colors[i][1].up) { + int rootIdx = findParent(colors[i][0].box); + twoPairs[rootIdx]++; + } + } + for (int i = 1; i <= N; i++) { + int rootIdx = findParent(colors[i][0].box); + if(twoPairs[rootIdx] >= 2) return true; + } + return false; + } + + private static int solve() { + makeCycle(); + if(isTwoPairsOnTop()) return -1; + + int ans = 0; + boolean[] check = new boolean[N + 1]; + for (int i = 1; i <= N; i++) { + int rootIdx = findParent(colors[i][0].box); + if(check[rootIdx]) continue; + + check[rootIdx] = true; + + if(subBoxCount[rootIdx] >= 2) { + ans += subBoxCount[rootIdx] + 1; + } + } + + return ans; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + + colors = new Color[N + 1][2]; + for (int i = 1; i <= N; i++) { + st = new StringTokenizer(br.readLine()); + int a = Integer.parseInt(st.nextToken()); + int b = Integer.parseInt(st.nextToken()); + if(colors[a][0] == null) colors[a][0] = new Color(i, true); + else colors[a][1] = new Color(i, true); + if(colors[b][0] == null) colors[b][0] = new Color(i, false); + else colors[b][1] = new Color(i, false); + } + + boxParent = new int[N + 1]; + subBoxCount = new int[N + 1]; + System.out.println(solve()); + } +} diff --git "a/BOJ/30000-35000\353\262\210/JW_30407.java" "b/BOJ/30000-35000\353\262\210/JW_30407.java" new file mode 100644 index 00000000..f920d4d3 --- /dev/null +++ "b/BOJ/30000-35000\353\262\210/JW_30407.java" @@ -0,0 +1,52 @@ +import java.util.ArrayDeque; +import java.util.Deque; + +public class JW_30407 { + + public static void main(String[] args) throws Exception { + int n = read(); + Deque dq = new ArrayDeque<>(); + int h = read(), d = read(), k = read(); + dq.offer(new int[] { h, d, 1, 0 }); + int t = 0, damage = 0, tempDamage = 0; + while (n-- > 0) { + t = dq.size(); + tempDamage = read(); + while (t-- > 0) { + int[] cur = dq.poll(); + damage = Math.max(0, tempDamage - cur[1]); // 받을 데미지 + // 현재 체력이 0 이하라면 건너뛰기 + if (cur[0] <= 0) + continue; + // 깜짝 놀래켰었다면 + if (cur[3] == 1) { + cur[3] = 0; + damage = 0; + } + // 깜짝 놀래킬 수 있다면 + if (cur[2] != 0) + dq.offer(new int[] { cur[0] - damage, cur[1], 0, 1 }); + dq.offer(new int[] { cur[0] - Math.max(0, damage - k), cur[1] + k, cur[2], cur[3] }); + dq.offer(new int[] { cur[0] - damage / 2, cur[1], cur[2], cur[3] }); + } + } + // 최댓값 갱신 + int maxH = 0; + while (!dq.isEmpty()) { + int[] cur = dq.poll(); + if (cur[0] <= 0) + continue; + maxH = Math.max(maxH, cur[0]); + } + System.out.println(maxH != 0 ? maxH : -1); + } + + private static int read() throws Exception { + int c, n = System.in.read() & 15; + while ((c = System.in.read()) >= 48) + n = (n << 3) + (n << 1) + (c & 15); + if (c == 13) + System.in.read(); + return n; + } +} \ No newline at end of file diff --git "a/BOJ/30000-35000\353\262\210/JY_32070.java" "b/BOJ/30000-35000\353\262\210/JY_32070.java" new file mode 100644 index 00000000..97acb3d9 --- /dev/null +++ "b/BOJ/30000-35000\353\262\210/JY_32070.java" @@ -0,0 +1,120 @@ +import java.io.*; +import java.util.*; + +public class JY_32070 { + static int N; + // cnt[i] 그룹의 공의 개수 == 그룹의 크기 + // rank[i] 트리의 깊이 + // toParis[] 한 그룹에서 상단에 위치한 공의 개수 + static int[] parent, cnt, topPairs; + static boolean[] solved; + static List[] ball; + + static int find(int u) { + if (parent[u] == u) return u; + return parent[u] = find(parent[u]); + } + + static void union(int a, int b) { + int pa = find(a); + int pb = find(b); + + if(pa == pb) return; + if(pa < pb) { + parent[pb] = pa; + cnt[pa] += cnt[pb]; + } else { + parent[pa] = pb; + cnt[pb] += cnt[pa]; + } + + } + + // 해당 집합의 크기 반환 + static int getCnt(int u) { + return cnt[find(u)]; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + N = Integer.parseInt(br.readLine()); + + ball = new ArrayList[N + 1]; + for (int i = 1; i <= N; i++) { + ball[i] = new ArrayList<>(); + } + + parent = new int[N + 1]; +// rank = new int[N + 1]; + cnt = new int[N + 1]; + topPairs = new int[N + 1]; + solved = new boolean[N + 1]; + + // 초기화 == 각 상자가 그룹장 + for (int i = 1; i <= N; i++) { + parent[i] = i; + cnt[i] = 1; + } + + for (int i = 1; i <= N; i++) { + StringTokenizer st = new StringTokenizer(br.readLine()); + int a = Integer.parseInt(st.nextToken()); + int b = Integer.parseInt(st.nextToken()); + + // 색깔이 a인 공의 절대적인 상자 위치 + ball[a].add(i * 2); + // 색깔이 b인 공의 절대적인 상자 위치 + ball[b].add(i * 2 + 1); + } + + System.out.println(Arrays.toString(ball)); + + // 같은 색 공이 있는 상자들을 병합 + for (int i = 1; i <= N; i++) { + union(ball[i].get(0) / 2, ball[i].get(1) / 2); + } + + System.out.println(">> parent: "+Arrays.toString(parent)); + System.out.println(">> cnt: "+Arrays.toString(cnt)); + // cnt[i] : i번째 상자가 속한 사이클의 상자의 개수 + + // 루트 노드의 topPairs 개수 증가 + // 짝수 : 상자의 상단에 있음 + // 홀수 : 상자의 하단에 있음 + for (int i = 1; i <= N; i++) { + // 색깔이 i인 공이 모두 각 상자의 상단에 있음 + if (ball[i].get(0) % 2 == 0 && ball[i].get(1) % 2 == 0) { + int rootIdx = find(ball[i].get(0) / 2); + System.out.println("i:"+i+" root:"+rootIdx); + topPairs[rootIdx]++; + } + } + + System.out.println("top: "+Arrays.toString(topPairs)); + + // 상자 그룹이 2개 이상이면 불가능 (-1 출력) + for (int i = 1; i <= N; i++) { + int rootIdx = find(ball[i].get(0) / 2); + if (topPairs[rootIdx] >= 2) { + System.out.println("-1"); + return; + } + } + + int ans = 0; + + // 최소 이동 횟수 계산 + for (int i = 1; i <= N; i++) { + int rootIdx = find(ball[i].get(0) / 2); + + if (solved[rootIdx]) continue; + + solved[rootIdx] = true; + int x = cnt[rootIdx]; + + if (x >= 2) ans += x + 1; + } + + System.out.println(ans); + } +} diff --git "a/BOJ/30000-35000\353\262\210/SB_30407.java" "b/BOJ/30000-35000\353\262\210/SB_30407.java" new file mode 100644 index 00000000..f3498fe5 --- /dev/null +++ "b/BOJ/30000-35000\353\262\210/SB_30407.java" @@ -0,0 +1,48 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +public class SB_30407 { + static int N, H, D, K; + static int[] attack; + static int ans = 0; + + private static void dfs(int depth, int hp, int d, int atk, boolean isUse) { + if (depth == N) { + ans = Math.max(ans, hp); + return; + } + if (hp <= ans || hp <= 0) return; + + int wounk = Math.max(0, atk - d); + dfs(depth + 1, hp - (wounk / 2), d, attack[depth + 1], isUse); + + int run = Math.max(0, atk - (d + K)); + dfs(depth + 1, hp - run, d + K, attack[depth + 1], isUse); + + if (!isUse) { + int fright = Math.max(0, atk - d); + dfs(depth + 1, hp - fright, d, 0, true); + } + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st; + + N = Integer.parseInt(br.readLine()); + st = new StringTokenizer(br.readLine()); + H = Integer.parseInt(st.nextToken()); // 체력 + D = Integer.parseInt(st.nextToken()); // 거리 + K = Integer.parseInt(st.nextToken()); // 이동 거리 + + attack = new int[N + 1]; + for (int i = 0; i < N; i++) { + attack[i] = Integer.parseInt(br.readLine()); + } + + dfs(0, H, D, attack[0], false); + System.out.println(ans <= 0 ? -1 : ans); + } +} diff --git "a/BOJ/5001-10000\353\262\210/JM_9944.java" "b/BOJ/5001-10000\353\262\210/JM_9944.java" new file mode 100644 index 00000000..a08d698a --- /dev/null +++ "b/BOJ/5001-10000\353\262\210/JM_9944.java" @@ -0,0 +1,109 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +public class JM_9944 { + static int N; + static int M; + static char[][] map; + private static final int[][] DIR = {{0, 1}, {-1, 0}, {1, 0}, {0, -1}}; + + private static boolean isRange(int y, int x) { + return 0 <= y && y < N && 0 <= x && x < M; + } + + private static int moveBack(int y, int x, int ny, int nx, int d) { + int moveCnt = 0; + while (!(y == ny && x == nx)) { + map[ny][nx] = '.'; + moveCnt += 1; + ny -= DIR[d][0]; + nx -= DIR[d][1]; + } + return moveCnt; + } + + private static int[] move(int y, int x, int d) { + int moveCnt = 0; + while (true) { + int ny = y + DIR[d][0]; + int nx = x + DIR[d][1]; + if(!isRange(ny, nx) || map[ny][nx] != '.') break; + map[ny][nx] = '#'; + moveCnt += 1; + y = ny; + x = nx; + } + return new int[]{y, x, moveCnt}; + } + + private static int dfs(int y, int x, int blankCnt) { + if(blankCnt == 0) { + return 0; + } + + int res = -1; + for (int d = 0; d < 4; d++) { + int[] next = move(y, x, d); + int ny = next[0]; + int nx = next[1]; + blankCnt -= next[2]; + + if(!(y == ny && x == nx)) { + int tmp = dfs(ny, nx, blankCnt); + if(tmp != -1 && (res == -1 || res > tmp + 1)) { + res = tmp + 1; + } + } + + blankCnt += moveBack(y, x, ny, nx, d); + } + + return res; + } + + private static int solve(int blankCnt) { + int res = -1; + + for (int i = 0; i < N; i++) { + for (int j = 0; j < M; j++) { + if(map[i][j] == '*') continue; + map[i][j] = '#'; + int tmp = dfs(i, j, blankCnt - 1); + if(tmp != -1 && (res == -1 || res > tmp)) { + res = tmp; + } + map[i][j] = '.'; + } + } + + return res; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st; + String line; + + int T = 1; + StringBuilder sb = new StringBuilder(); + while((line = br.readLine()) != null && line.length() > 0) { + st = new StringTokenizer(line); + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + + int blankCnt = 0; + map = new char[N][M]; + for (int i = 0; i < N; i++) { + map[i] = br.readLine().toCharArray(); + for (int j = 0; j < M; j++) { + if(map[i][j] == '.') blankCnt++; + } + } + sb.append("Case ").append(T).append(": ").append(solve(blankCnt)).append("\n"); + T++; + } + System.out.println(sb); + } +} diff --git "a/BOJ/5001-10000\353\262\210/JY_9944.java" "b/BOJ/5001-10000\353\262\210/JY_9944.java" new file mode 100644 index 00000000..63301897 --- /dev/null +++ "b/BOJ/5001-10000\353\262\210/JY_9944.java" @@ -0,0 +1,113 @@ +import java.util.*; +import java.io.*; +public class JY_9944 { + + static final int INF = 1000001; + static int N, M; + static char[][] g; + // 상 하 좌 우 + static int[] dx = {-1, 1, 0, 0}; + static int[] dy = {0, 0, -1, 1}; + static boolean[][] visited; + static int eCnt = 0; + static int ans; + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st; + String line; + + int t = 1; + while((line = br.readLine()) != null && !line.isEmpty()) { + st = new StringTokenizer(line); + + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + + g = new char[N][M]; + eCnt = 0; + for(int i=0; i=0 && x=0 && y= ans || cnt >= INF) return; + + visited[x][y] = true; + int nx = x + dx[dir]; + int ny = y + dy[dir]; + + // 현재 방향으로 갈 수 있음 + if(canGo(nx, ny)) { + dfs(nx, ny, dir, mCnt+1, cnt); + } + // 갈 수 없음 -> 방햔 전환 필요(단계 증가) + else { + boolean isMove = false; + for(int i=0; i<4; i++) { + if(i == dir) continue; + nx = x + dx[i]; + ny = y + dy[i]; + if(!canGo(nx, ny)) continue; + + isMove = true; + dfs(nx, ny, i, mCnt+1, cnt+1); + } + + } + visited[x][y] = false; + } + +} diff --git "a/BOJ/5001-10000\353\262\210/SB_9944.java" "b/BOJ/5001-10000\353\262\210/SB_9944.java" new file mode 100644 index 00000000..116616d3 --- /dev/null +++ "b/BOJ/5001-10000\353\262\210/SB_9944.java" @@ -0,0 +1,97 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +public class SB_9944 { + static int N, M; + static char[][] board; + static int mn; + static final int INF = Integer.MAX_VALUE; + static int[] dx = {-1, 1, 0, 0}; + static int[] dy = {0, 0, -1, 1}; + + private static boolean isAllVisited(boolean[][] visited) { + for (int i = 0; i < N; i++) { + for (int j = 0; j < M; j++) { + if (!visited[i][j]) return false; + } + } + return true; + } + + private static void dfs(int x, int y, int cnt, boolean[][] visited) { + if (cnt >= mn) return; // 가지 치기 + + boolean canMove = false; + for (int i = 0; i < 4; i++) { + int nx = x + dx[i]; + int ny = y + dy[i]; + if (!isValid(nx, ny) || visited[nx][ny]) continue; + canMove = true; + + while (isValid(nx, ny) && !visited[nx][ny]) { + visited[nx][ny] = true; + nx += dx[i]; + ny += dy[i]; + } + + nx -= dx[i]; // 위에서 한 칸 삐져나오니까 한칸 뒤로가기 + ny -= dy[i]; + + dfs(nx, ny, cnt + 1, visited); // 한 방향 당 cnt++ + + while (nx != x || ny != y) { // 처음위치까지 이동 + visited[nx][ny] = false; + nx -= dx[i]; + ny -= dy[i]; + } + } + + if (!canMove && isAllVisited(visited)) { // 더이상 움직일 수 없고 모든 칸 방문 시 mn 업데이트 + mn = Math.min(mn, cnt); + } + } + + private static boolean isValid(int x, int y) { + return 0 <= x && x < N && 0 <= y && y < M; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st; + StringBuilder sb = new StringBuilder(); + + String line; + int turn = 1; + while ((line = br.readLine()) != null && !line.isEmpty()) { + st = new StringTokenizer(line); + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + + board = new char[N][M]; + boolean[][] visited = new boolean[N][M]; + mn = INF; + + for (int i = 0; i < N; i++) { + line = br.readLine(); + for (int j = 0; j < M; j++) { + board[i][j] = line.charAt(j); + if (board[i][j] == '*') visited[i][j] = true; + } + } + + for (int i = 0; i < N; i++) { + for (int j = 0; j < M; j++) { + if (board[i][j] == '*' || visited[i][j]) continue; + visited[i][j] = true; + dfs(i, j, 0, visited); + visited[i][j] = false; + } + } + sb.append("Case ").append(turn++).append(": ").append(mn == INF ? -1 : mn).append("\n"); + } + + System.out.println(sb); + } +} diff --git "a/CodeTree/2015-2016\353\205\204/JW_2\352\260\234\354\235\230_\354\202\254\355\203\225.java" "b/CodeTree/2015-2016\353\205\204/JW_2\352\260\234\354\235\230_\354\202\254\355\203\225.java" new file mode 100644 index 00000000..1293d324 --- /dev/null +++ "b/CodeTree/2015-2016\353\205\204/JW_2\352\260\234\354\235\230_\354\202\254\355\203\225.java" @@ -0,0 +1,114 @@ +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.StringTokenizer; + +public class JW_2개의_사탕 { + + static int n, m, g; // 각 인덱스 + static boolean[][] board, visited; + static int[] dy = { -1, 1, 0, 0 }, dx = { 0, 0, -1, 1 }; + + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + n = Integer.parseInt(st.nextToken()); + m = Integer.parseInt(st.nextToken()); + board = new boolean[n][m]; + visited = new boolean[n * m][n * m]; // 빨간, 파란 사탕 각각 방문처리 + int r = 0, b = 0; + for (int i = 0; i < n; i++) { + char[] line = br.readLine().toCharArray(); + for (int j = 0; j < m; j++) { + char c = line[j]; + if (c == '#') + board[i][j] = true; + else if (c == 'R') + r = i * m + j; // 빨간 사탕의 인덱스 + else if (c == 'B') + b = i * m + j; // 파란 사탕의 인덱스 + else if (c == 'O') + g = i * m + j; // 구멍의 인덱스 + } + } + System.out.println(bfs(r, b)); + } + + private static int bfs(int sr, int sb) { + Deque dq = new ArrayDeque<>(); + dq.offer(new int[] { sr, sb }); + visited[sr][sb] = true; + int time = 0; + while (!dq.isEmpty()) { + int t = dq.size(); + while (t-- > 0) { + int[] cur = dq.poll(); + int r = cur[0], b = cur[1]; + // 파란 사탕이 들어갔다면 다음 탐색 + if (b == g) + continue; + // 빨간 사탕이 들어갔다면 종료 + if (r == g) + return time; + for (int i = 0; i < 4; i++) { + int[] next = move(i, r, b); + // 잘못된 움직임일 경우 다음 탐색 + if ((next[0] == -1 && next[1] == -1) || visited[next[0]][next[1]]) + continue; + visited[next[0]][next[1]] = true; + dq.offer(next); + } + } + time++; + if(time > 10) + return -1; + } + return -1; + } + + private static int[] move(int dir, int r, int b) { + int nr = goStraight(dir, r), nb = goStraight(dir, b); // 상자를 기울인 방향으로 직선 운동 + // 두 인덱스가 겹쳤을 경우 + if (nr == nb) { + // 구멍에 빠졌다면 → 두 사탕이 모두 구멍에 빠짐 + if (nr == g) + return new int[] { -1, -1 }; // 잘못된 움직임을 알려주기 위한 반환 + // 상하좌우 + // 부딪혔을 경우, 인덱스를 조정 + switch (dir) { + case 0: + if (r < b) nb += m; + else nr += m; + break; + case 1: + if (r < b) nr -= m; + else nb -= m; + break; + case 2: + if (r < b) nb += 1; + else nr += 1; + break; + case 3: + if (r < b) nr -= 1; + else nb -= 1; + break; + } + } + return new int[] { nr, nb }; + } + + // 직선 움직임 구현 + private static int goStraight(int dir, int cur) { + int y = cur / m, x = cur % m; + int gy = g / m, gx = g % m; + while (!board[y + dy[dir]][x + dx[dir]]) { + y += dy[dir]; + x += dx[dir]; + // 구멍에 들어갔을 경우 종료 + if (y == gy && x == gx) + return y * m + x; + } + return y * m + x; + } +} diff --git "a/CodeTree/2015-2016\353\205\204/JY_2\352\260\234\354\235\230_\354\202\254\355\203\225.java" "b/CodeTree/2015-2016\353\205\204/JY_2\352\260\234\354\235\230_\354\202\254\355\203\225.java" new file mode 100644 index 00000000..24465a80 --- /dev/null +++ "b/CodeTree/2015-2016\353\205\204/JY_2\352\260\234\354\235\230_\354\202\254\355\203\225.java" @@ -0,0 +1,143 @@ +import java.io.*; +import java.util.*; +public class JY_2개의_사탕 { + + static int N, M; + static char[][] g; + // 상 하 좌 우 + static int[] dx = {-1, 1, 0, 0}; + static int[] dy = {0, 0, -1, 1}; + static class Candy { + int x, y; + + public Candy(int x, int y) { + super(); + this.x = x; + this.y = y; + } + + @Override + public String toString() { + return "Candy [x=" + x + ", y=" + y + "]"; + } + + } + static int ans; + + public static void main(String[] args) throws IOException{ + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + + g = new char[N][M]; + Candy red = new Candy(-1, -1); + Candy blue = new Candy(-1, -1); + + for(int i=0; i 10) System.out.println(-1); + else System.out.println(ans); + + + } + public static void printG() { + for(int i=0; i 10) return; + // 이미 구해진 값보다 많다면 중단 + if(cnt > ans) return; + + for(int i=0; i<4; i++) { + Candy nr = move(r, i); + Candy nb = move(b, i); + + // 둘 위치가 같음 -> 위치 재조정 + if(nr.x == nb.x && nr.y == nb.y) { + // 같은 위치가 도착점이면 X + if(g[nr.x][nr.y] == 'O') continue; + // 상 + if(i == 0) { + if(r.x < b.x) { + nb.x += 1; + } else { + nr.x += 1; + } + } + // 하 + else if(i == 1) { + if(r.x > b.x) { + nb.x -= 1; + } else { + nr.x -= 1; + } + } + // 좌 + else if(i == 2) { + if(r.y < b.y) { + nb.y += 1; + } else { + nr.y += 1; + } + } + // 우 + else { + if(r.y > b.y) { + nb.y -= 1; + } else { + nr.y -= 1; + } + } + } + if(r.x == nr.x && r.y == nr.y && b.x == nb.x && b.y == nb.y) continue; + exit(nr, nb, cnt+1); + + + } + } + public static Candy move(Candy c, int dir) { + Candy nc = new Candy(c.x, c.y); + while(true) { + // 현제 위치가 도착점이면 중단 + if(g[nc.x][nc.y] == 'O') break; + int nx = nc.x + dx[dir]; + int ny = nc.y + dy[dir]; + + // 다음이 벽이면 중단 + if(g[nx][ny] == '#') break; + nc.x = nx; + nc.y = ny; + } + return nc; + } + +} diff --git "a/CodeTree/2015-2016\353\205\204/SB_\353\221\220\352\260\234\354\235\230\354\202\254\355\203\225.java" "b/CodeTree/2015-2016\353\205\204/SB_\353\221\220\352\260\234\354\235\230\354\202\254\355\203\225.java" new file mode 100644 index 00000000..0e233830 --- /dev/null +++ "b/CodeTree/2015-2016\353\205\204/SB_\353\221\220\352\260\234\354\235\230\354\202\254\355\203\225.java" @@ -0,0 +1,111 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.*; + +public class SB_두개의사탕 { + static int N, M; + static char[][] board; + static int[] blue = new int[2]; + static int[] red = new int[2]; + static int[] dx = {-1, 1, 0, 0}; + static int[] dy = {0, 0, -1, 1}; + + private static Res tilt(int x, int y, int i) { // 방향에 따라 기울이기 + int move = 0; + while (board[x + dx[i]][y + dy[i]] != '#' && board[x][y] != 'O') { // 다음에 위치할 값이 #이 아니고 현재 값이 도착점이 아니면 계속 움직임 + x += dx[i]; + y += dy[i]; // 좌표값 갱신 (i방향으로 이동) + move++; + } + return new Res(x, y, move, board[x][y] == 'O'); + } + + private static int bfs() { + Deque que = new ArrayDeque<>(); + Set visited = new HashSet<>(); + + que.offer(new Node(red[0], red[1], blue[0], blue[1], 0)); + visited.add("" + red[0] + red[1] + blue[0] + blue[1]); + + while (!que.isEmpty()) { + Node cur = que.poll(); + if (cur.cnt >= 10) return -1; + + for (int i = 0; i < 4; i++) { + // 구슬 각각 기울인 값 + Res nR = tilt(cur.rx, cur.ry, i); + Res nB = tilt(cur.bx, cur.by, i); + + if (nB.isGoal) continue; + if (nR.isGoal) return cur.cnt + 1; + if (nB.x == nR.x && nB.y == nR.y) { // 구슬이 같은 위치에 있다고 나왔을땐, 거리를 통해 실제 위치 파악 + if (nR.mv > nB.mv){ // 이동거리가 많은 것이 늦게 온것, 따라서 기존 위치보다 한 칸 뒤에 존재 + nR.x -= dx[i]; + nR.y -= dy[i]; + } else{ + nB.x -= dx[i]; + nB.y -= dy[i]; + } + } + + String state = "" + nR.x + nR.y + nB.x + nB.y; + if (!visited.contains(state)) { + visited.add(state); + que.offer(new Node(nR.x, nR.y, nB.x, nB.y, cur.cnt + 1)); + } + } + } + return -1; + } + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + + board = new char[N][M]; + + for (int i = 0; i < N; i++) { + String line = br.readLine(); + for (int j = 0; j < M; j++) { + board[i][j] = line.charAt(j); + if (board[i][j]=='B') { + blue[0] = i; + blue[1] = j; + } + else if (board[i][j]=='R') { + red[0] = i; + red[1] = j; + } + } + } + + System.out.println(bfs()); + } + + private static class Node{ + int rx, ry, bx, by, cnt; + + public Node(int rx, int ry, int bx, int by, int cnt) { + this.rx = rx; + this.ry = ry; + this.bx = bx; + this.by = by; + this.cnt = cnt; + } + } + + private static class Res{ + int x, y, mv; + boolean isGoal; + + public Res(int x, int y, int mv, boolean isGoal) { + this.x = x; + this.y = y; + this.mv = mv; + this.isGoal = isGoal; + } + } +} diff --git "a/CodeTree/2017-2018\353\205\204/JM_\353\263\221\354\233\220_\352\261\260\353\246\254_\354\265\234\354\206\214\355\231\224\355\225\230\352\270\260.java" "b/CodeTree/2017-2018\353\205\204/JM_\353\263\221\354\233\220_\352\261\260\353\246\254_\354\265\234\354\206\214\355\231\224\355\225\230\352\270\260.java" new file mode 100644 index 00000000..b202b00b --- /dev/null +++ "b/CodeTree/2017-2018\353\205\204/JM_\353\263\221\354\233\220_\352\261\260\353\246\254_\354\265\234\354\206\214\355\231\224\355\225\230\352\270\260.java" @@ -0,0 +1,78 @@ +import java.util.*; +import java.io.*; + +public class JM_병원_거리_최소화하기 { + static class Point { + int y, x; + public Point(int y, int x) { + this.y = y; + this.x = x; + } + } + static int N; + static int M; + static List hospital; + static List person; + static int answer; + static int[][] dist; + + private static int calc(int picked) { + int sum = 0; + for(int i = 0; i < person.size(); i++) { + int pDist = Integer.MAX_VALUE; + for(int j = 0; j < hospital.size(); j++) { + if((picked & (1 << j)) == 0) continue; + if(pDist > dist[i][j]) pDist = dist[i][j]; + } + sum += pDist; + } + return sum; + } + + private static void pick(int next, int index, int picked) { + if(index == M) { + int currTotalSum = calc(picked); + if(answer > currTotalSum) answer = currTotalSum; + return; + } + + for(int i = next; i < hospital.size(); i++) { + pick(i + 1, index + 1, picked | (1 << i)); + } + + } + + private static void initDist() { + for(int i = 0; i < person.size(); i++) { + for(int j = 0; j < hospital.size(); j++) { + dist[i][j] = Math.abs(person.get(i).y - hospital.get(j).y) + Math.abs(person.get(i).x - hospital.get(j).x); + } + } + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + + hospital = new ArrayList<>(); + person = new ArrayList<>(); + + for(int i = 0; i < N; i++) { + st = new StringTokenizer(br.readLine()); + for(int j = 0; j < N; j++) { + int x = Integer.parseInt(st.nextToken()); + if(x == 1) person.add(new Point(i, j)); + else if(x == 2) hospital.add(new Point(i, j)); + } + } + + dist = new int[person.size()][hospital.size()]; + initDist(); + + answer = Integer.MAX_VALUE; + pick(0, 0, 0); + System.out.println(answer); + } +} diff --git "a/CodeTree/2017-2018\353\205\204/JW_\353\263\221\354\233\220_\352\261\260\353\246\254_\354\265\234\354\206\214\355\231\224\355\225\230\352\270\260.java" "b/CodeTree/2017-2018\353\205\204/JW_\353\263\221\354\233\220_\352\261\260\353\246\254_\354\265\234\354\206\214\355\231\224\355\225\230\352\270\260.java" new file mode 100644 index 00000000..d7d3e48f --- /dev/null +++ "b/CodeTree/2017-2018\353\205\204/JW_\353\263\221\354\233\220_\352\261\260\353\246\254_\354\265\234\354\206\214\355\231\224\355\225\230\352\270\260.java" @@ -0,0 +1,63 @@ +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.StringTokenizer; + +public class JW_병원_거리_최소화하기 { + + static int n, m, minDistance = Integer.MAX_VALUE; + static ArrayList pArr = new ArrayList<>(); // 사람들의 좌표 + static ArrayList hArr = new ArrayList<>(); // 병원들의 좌표 + static int[][] distances; // 사람 → 병원의 거리 + static int[] choices; // 조합 배열 + + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + n = Integer.parseInt(st.nextToken()); + m = Integer.parseInt(st.nextToken()); + for (int i = 0; i < n; i++) { + st = new StringTokenizer(br.readLine()); + for (int j = 0; j < n; j++) { + int p = Integer.parseInt(st.nextToken()); + if (p == 1) + pArr.add(new int[] { i, j }); + else if (p == 2) + hArr.add(new int[] { i, j }); + } + } + // 좌표로 거리 계산 + distances = new int[pArr.size()][hArr.size()]; + for (int i = 0; i < pArr.size(); i++) + for (int j = 0; j < hArr.size(); j++) { + int py = pArr.get(i)[0], px = pArr.get(i)[1]; + int hy = hArr.get(j)[0], hx = hArr.get(j)[1]; + distances[i][j] = Math.abs(py - hy) + Math.abs(px - hx); + } + choices = new int[m]; + recursive(0, 0); + System.out.println(minDistance); + } + + // 재귀로 조합 계산 + private static void recursive(int depth, int p) { + // 종료 조건 + if (depth == m) { + int totalDistance = 0; + for (int i = 0; i < pArr.size(); i++) { + int distance = Integer.MAX_VALUE; + // 뽑은 병원들까지의 거리들 중 최소 거리 + for (int j = 0; j < m; j++) + distance = Math.min(distance, distances[i][choices[j]]); + totalDistance += distance; + } + minDistance = Math.min(minDistance, totalDistance); + return; + } + // 다음 재귀 호출 + for (int i = p; i < hArr.size(); i++) { + choices[depth] = i; + recursive(depth + 1, i + 1); + } + } +} \ No newline at end of file diff --git "a/CodeTree/2017-2018\353\205\204/JY_\353\263\221\354\233\220_\352\261\260\353\246\254_\354\265\234\354\206\214\355\231\224\355\225\230\352\270\260.java" "b/CodeTree/2017-2018\353\205\204/JY_\353\263\221\354\233\220_\352\261\260\353\246\254_\354\265\234\354\206\214\355\231\224\355\225\230\352\270\260.java" new file mode 100644 index 00000000..aee25d59 --- /dev/null +++ "b/CodeTree/2017-2018\353\205\204/JY_\353\263\221\354\233\220_\352\261\260\353\246\254_\354\265\234\354\206\214\355\231\224\355\225\230\352\270\260.java" @@ -0,0 +1,90 @@ +import java.io.*; +import java.util.*; +public class JY_병원_거리_최소화하기 { + + static int N, M; + static int[][] g; + static Map hMap; + static List tList; + static int ans; + static class Hospital { + int num, x, y; + + public Hospital(int num, int x, int y) { + super(); + this.num = num; + this.x = x; + this.y = y; + } + + @Override + public String toString() { + return "Hospital [num=" + num + ", x=" + x + ", y=" + y + "]"; + } + + } + + public static void main(String[] args) throws IOException{ + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + + g = new int[N][N]; + hMap = new HashMap<>(); + int n = 0; + for(int i=0; i(); + ans = Integer.MAX_VALUE; + // 최대 경우의 수 : 100(사람수) * 13C7 * 7 + comb(0, 0); + + System.out.println(ans); + } + public static void comb(int depth, int start) { + if(depth == M) { + int score = find(tList); + ans = Math.min(ans, score); + return; + } + for(int i=start; i hList) { + int total = 0; + // 사람 반복 + for(int i=0; i people = new ArrayList<>(); + static List hospital = new ArrayList<>(); + static List> combi = new ArrayList<>(); + static int ans = Integer.MAX_VALUE; + + private static void dfs(int start, List tmp) { + if (tmp.size() == M) { + combi.add(new ArrayList<>(tmp)); + return; + } + + for (int i = start; i < hospital.size(); i++) { + tmp.add(i); + dfs(i + 1, tmp); + tmp.remove(tmp.size() - 1); + } + } + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + + board = new int[N][N]; + for (int i = 0; i < N; i++) { + st = new StringTokenizer(br.readLine()); + for (int j = 0; j < N; j++) { + board[i][j] = Integer.parseInt(st.nextToken()); + if (board[i][j]==1) people.add(new Node(i, j)); + else if (board[i][j]==2) hospital.add(new Node(i, j)); + } + } + + // 병원 선택 조합 생성 + dfs(0, new ArrayList()); + + // 각 사람별 최소 병원 구간 구하기 + for (List lst: combi) { + int tmp = 0; + for (Node p : people) { + int mn = Integer.MAX_VALUE; + for (Integer i : lst) { // 각 사람이 병원을 돌며, 최소 병원길이 찾기 + Node h = hospital.get(i); + int dist = Math.abs(h.x - p.x) + Math.abs(h.y - p.y); + mn = Math.min(mn, dist); + } + tmp += mn; // 최소 병원길이 더해주기 + if (tmp >= ans) break; + } + ans = Math.min(ans, tmp); + } + + System.out.println(ans); + } + static class Node{ + int x, y; + + public Node(int x, int y) { + this.x = x; + this.y = y; + } + } +} diff --git "a/CodeTree/2021-2022\353\205\204/JM_\353\202\230\353\254\264\353\260\225\353\251\270.java" "b/CodeTree/2021-2022\353\205\204/JM_\353\202\230\353\254\264\353\260\225\353\251\270.java" new file mode 100644 index 00000000..ceb6e33b --- /dev/null +++ "b/CodeTree/2021-2022\353\205\204/JM_\353\202\230\353\254\264\353\260\225\353\251\270.java" @@ -0,0 +1,163 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.StringTokenizer; + +public class JM_나무박멸 { + static int N; + static int M; // 박멸이 진행되는 년 수 + static int K; // 제초제의 확산 범위 K + static int C; // 제초제가 남아있는 년 수 C + static int[][] map; // 0(빈칸), -1(벽) + static final int[][] DIR = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1}}; + static int[][] herbicide; + + private static boolean inRange(int y, int x) { + return 0 <= y && y < N && 0 <= x && x < N; + } + + private static void reduceHerbicide() { + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + if(herbicide[i][j] <= 0) continue; + herbicide[i][j] -= 1; + } + } + } + + private static int[] findMaxRemovedTreePos() { + int[] pos = new int[3]; + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + if(map[i][j] <= 0) continue; + + int removedTree = map[i][j]; + for (int d = 4; d < 8; d++) { + int ny = i; + int nx = j; + int k = 0; + while (k++ < K) { + ny += DIR[d][0]; + nx += DIR[d][1]; + if(!inRange(ny, nx) || map[ny][nx] == 0 || map[ny][nx] == -1) break; + removedTree += map[ny][nx]; + } + } + + if(removedTree > pos[2]) { + pos[0] = i; + pos[1] = j; + pos[2] = removedTree; + } + } + } + return pos; + } + + private static int sprayHerbicide() { + int[] pos = findMaxRemovedTreePos(); + int y = pos[0]; + int x = pos[1]; + int removedTree = pos[2]; + + map[y][x] = 0; + herbicide[y][x] = C + 1; + for (int d = 4; d < 8; d++) { + int ny = y; + int nx = x; + int k = 0; + while (k++ < K) { + ny += DIR[d][0]; + nx += DIR[d][1]; + if(!inRange(ny, nx)) break; + herbicide[ny][nx] = C + 1; + if(map[ny][nx] <= 0) break; + map[ny][nx] = 0; + } + } + + return removedTree; + } + + private static int countReproduction(int y, int x) { + int cnt = 0; + for (int k = 0; k < 4; k++) { + int ny = y + DIR[k][0]; + int nx = x + DIR[k][1]; + if(!inRange(ny, nx) || map[ny][nx] != 0 || herbicide[ny][nx] > 0) continue; + cnt++; + } + return cnt == 0 ? 0 : map[y][x] / cnt; + } + + private static void reproduce() { + int[][] tmp = new int[N][N]; + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + tmp[i][j] = map[i][j]; + } + } + + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + if(map[i][j] <= 0) continue; + + int reproduction = countReproduction(i, j); + if(reproduction == 0) continue; + for (int d = 0; d < 4; d++) { + int ny = i + DIR[d][0]; + int nx = j + DIR[d][1]; + if(!inRange(ny, nx) || map[ny][nx] != 0 || herbicide[ny][nx] > 0) continue; + tmp[ny][nx] += reproduction; + } + } + } + map = tmp; + } + + private static void growUp() { + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + if(map[i][j] <= 0) continue; + for (int d = 0; d < 4; d++) { + int ny = i + DIR[d][0]; + int nx = j + DIR[d][1]; + if(!inRange(ny, nx) || map[ny][nx] <= 0) continue; + map[i][j] += 1; + } + } + } + } + + private static int solve() { + int removedTree = 0; + + while (M-- > 0) { + reduceHerbicide(); + growUp(); + reproduce(); + removedTree += sprayHerbicide(); + } + + return removedTree; + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + K = Integer.parseInt(st.nextToken()); + C = Integer.parseInt(st.nextToken()); + + herbicide = new int[N][N]; + map = new int[N][N]; + for (int i = 0; i < N; i++) { + st = new StringTokenizer(br.readLine()); + for (int j = 0; j < N; j++) { + map[i][j] = Integer.parseInt(st.nextToken()); + } + } + System.out.println(solve()); + } +} diff --git "a/CodeTree/2021-2022\353\205\204/JW_Sam\354\235\230_\355\224\274\354\236\220\355\225\231\352\265\220.java" "b/CodeTree/2021-2022\353\205\204/JW_Sam\354\235\230_\355\224\274\354\236\220\355\225\231\352\265\220.java" new file mode 100644 index 00000000..4dae7725 --- /dev/null +++ "b/CodeTree/2021-2022\353\205\204/JW_Sam\354\235\230_\355\224\274\354\236\220\355\225\231\352\265\220.java" @@ -0,0 +1,154 @@ +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.StringTokenizer; + +public class JW_Sam의_피자학교 { + + static int n, k; + static Deque dq = new ArrayDeque<>(); + static int maxValue = 0, minValue = 3001; + static int H, W, R; // 초기 크기 + static int h, w, r; // 변하는 크기 + static int[][] dough; // 피자 도우 + static int[] dy = { 0, -1, 0, 1 }, dx = { -1, 0, 1, 0 }; + + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + n = Integer.parseInt(st.nextToken()); + k = Integer.parseInt(st.nextToken()); + st = new StringTokenizer(br.readLine()); + int v; + for (int i = 0; i < n; i++) { + v = Integer.parseInt(st.nextToken()); + dq.offer(v); + maxValue = Math.max(maxValue, v); + minValue = Math.min(minValue, v); + } + calculateDoughSize(); // 빙글빙글 접을 때의 사이즈 계산 + int time = 0; + while (maxValue - minValue > k) { + initDough(); // 빙글빙글 접기 + press(); // 누르기 + outspread(); // 펼치기 + halfDough(); // 절반씩 접기 + press(); // 누르기 + outspread(); // 펼치기 + judge(); // 최대, 최솟값 갱신 + time++; + } + System.out.println(time); + } + + // 빙글빙글 말 떄의 사이즈 계산 + private static void calculateDoughSize() { + int i = 0; + while ((int) ((i + 4) / 2) * (int) ((i + 3) / 2) <= n) + i++; + H = (i + 3) / 2; + W = (i + 2) / 2; + R = n - H * W; + } + + // 빙글빙글 접기 + private static void initDough() { + h = H; + w = W; + r = R; + dough = new int[h][w + r]; + // 사용하면 안되는 곳에 -1값 삽입 + for (int i = 0; i < h - 1; i++) + for (int j = 0; j < r; j++) + dough[i][w + j] = -1; + int y = h - 1, x = w + r - 1, dir = 0; + while (!dq.isEmpty()) { + dough[y][x] = dq.pollLast(); + if (dough[y][x] == minValue) + dough[y][x]++; + // 부딪히거나 값이 있는 곳이라면 회전 + if (!isValid(y + dy[dir], x + dx[dir]) || dough[y + dy[dir]][x + dx[dir]] != 0) + dir = (dir + 1) % 4; + y += dy[dir]; + x += dx[dir]; + } + } + + // 절반씩 접기 + private static void halfDough() { + h = 4; + w = n / 4; + r = 0; + dough = new int[h][w]; + for (int i = w - 1; i >= 0; i--) + dough[3][i] = dq.pollLast(); + for (int i = w - 1; i >= 0; i--) + dough[2][i] = dq.pollFirst(); + for (int i = 0; i < w; i++) + dough[1][i] = dq.pollFirst(); + for (int i = 0; i < w; i++) + dough[0][i] = dq.pollLast(); + } + + // 누르기 + private static void press() { + int[][] temp = new int[h][w + r]; // 변화량을 저장할 배열 + int ny, nx, d; + for (int y = 0; y < h; y++) + for (int x = 0; x < w + r; x++) { + // 사용하지 않는 칸 스킵 + if (dough[y][x] == -1) + continue; + for (int dir = 2; dir < 4; dir++) { + ny = y + dy[dir]; + nx = x + dx[dir]; + // 좌 하에서 평균 계산 후 맞춰주기 + if (isValid(ny, nx) && dough[ny][nx] != -1) { + d = Math.abs(dough[y][x] - dough[ny][nx]) / 5; + if (dough[y][x] > dough[ny][nx]) { + temp[y][x] -= d; + temp[ny][nx] += d; + } else if (dough[y][x] < dough[ny][nx]) { + temp[y][x] += d; + temp[ny][nx] -= d; + } + } + } + } + // 변화량 계산 + for (int y = 0; y < h; y++) + for (int x = 0; x < w + r; x++) { + if (temp[y][x] == 0) + continue; + dough[y][x] += temp[y][x]; + } + } + + // 펼치기 + private static void outspread() { + maxValue = 0; + minValue = 3001; + for (int x = 0; x < w + r; x++) + for (int y = h - 1; y >= 0; y--) { + if (dough[y][x] == -1) + break; + dq.offer(dough[y][x]); + } + } + + + // 최댓값 최솟값 갱신 + private static void judge() { + for (int y = 0; y < h; y++) + for (int x = 0; x < w; x++) { + maxValue = Math.max(maxValue, dough[y][x]); + minValue = Math.min(minValue, dough[y][x]); + } + } + + // 유효성 검사 + private static boolean isValid(int y, int x) { + return 0 <= y && y < h && 0 <= x && x < w + r; + } +} \ No newline at end of file diff --git "a/CodeTree/2021-2022\353\205\204/JW_\353\202\230\353\254\264\353\260\225\353\251\270.java" "b/CodeTree/2021-2022\353\205\204/JW_\353\202\230\353\254\264\353\260\225\353\251\270.java" new file mode 100644 index 00000000..b0f4f92c --- /dev/null +++ "b/CodeTree/2021-2022\353\205\204/JW_\353\202\230\353\254\264\353\260\225\353\251\270.java" @@ -0,0 +1,136 @@ +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.PriorityQueue; +import java.util.StringTokenizer; + +public class JW_나무박멸 { + + static int n, m, k, c; + static int[][] board, visited; + static int[] dy = { -1, 1, 0, 0, -1, -1, 1, 1 }, dx = { 0, 0, -1, 1, -1, 1, 1, -1 }; + + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + n = Integer.parseInt(st.nextToken()); + m = Integer.parseInt(st.nextToken()); + k = Integer.parseInt(st.nextToken()); + c = Integer.parseInt(st.nextToken()); + board = new int[n][n]; + visited = new int[n][n]; + for (int i = 0; i < n; i++) { + st = new StringTokenizer(br.readLine()); + for (int j = 0; j < n; j++) + board[i][j] = Integer.parseInt(st.nextToken()); + } + int total = 0; + while (m-- > 0) { + grow(); + breed(); + int[] target = find(); + total += target[2]; + if (target[0] == -1 && target[1] == -1) + break; + kill(target); + heal(); + } + System.out.println(total); + } + + private static void heal() { + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) + if (visited[i][j] > 0) + visited[i][j]--; + } + + private static void grow() { + int[][] dBoard = new int[n][n]; + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) { + if (board[i][j] > 0) { + for (int d = 0; d < 4; d++) { + int ny = i + dy[d], nx = j + dx[d]; + if (isValid(ny, nx) && board[ny][nx] > 0) + dBoard[i][j]++; + } + } + } + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) + board[i][j] += dBoard[i][j]; + } + + private static void breed() { + Deque dq = new ArrayDeque<>(); + int[][] dBoard = new int[n][n]; + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) { + if (board[i][j] > 0) { + for (int d = 0; d < 4; d++) { + int ny = i + dy[d], nx = j + dx[d]; + if (isValid(ny, nx) && visited[ny][nx] == 0 && board[ny][nx] == 0) + dq.offer(new int[] { ny, nx }); + } + if (dq.isEmpty()) + continue; + int amount = board[i][j] / dq.size(); + while (!dq.isEmpty()) { + int[] pos = dq.poll(); + dBoard[pos[0]][pos[1]] += amount; + } + } + } + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) + board[i][j] += dBoard[i][j]; + } + + private static int[] find() { + PriorityQueue pq = new PriorityQueue<>( + (o1, o2) -> o1[2] != o2[2] ? o2[2] - o1[2] : o1[0] != o2[0] ? o1[0] - o2[0] : o1[1] - o2[1]); + for (int i = 0; i < n; i++) + for (int j = 0; j < n; j++) + if (board[i][j] > 0) { + int sum = board[i][j]; + for (int d = 4; d < 8; d++) { + for (int l = 1; l <= k; l++) { + int ny = i + dy[d] * l, nx = j + dx[d] * l; + if (isValid(ny, nx) && board[ny][nx] > 0) + sum += board[ny][nx]; + else + break; + } + } + pq.offer(new int[] { i, j, sum }); + } + if (pq.isEmpty()) + return new int[] { -1, -1, 0 }; + return pq.poll(); + } + + private static void kill(int[] target) { + int y = target[0], x = target[1]; + board[y][x] = 0; + visited[y][x] = c + 1; + for (int d = 4; d < 8; d++) { + for (int l = 1; l <= k; l++) { + int ny = y + dy[d] * l, nx = x + dx[d] * l; + if (isValid(ny, nx)) { + visited[ny][nx] = c + 1; + if (board[ny][nx] <= 0) { + break; + } else { + board[ny][nx] = 0; + } + } + } + } + } + + private static boolean isValid(int y, int x) { + return 0 <= y && y < n && 0 <= x && x < n; + } +} diff --git "a/CodeTree/2021-2022\353\205\204/JY_Sam\354\235\230_\355\224\274\354\236\220\355\225\231\352\265\220.java" "b/CodeTree/2021-2022\353\205\204/JY_Sam\354\235\230_\355\224\274\354\236\220\355\225\231\352\265\220.java" new file mode 100644 index 00000000..e13bb7c2 --- /dev/null +++ "b/CodeTree/2021-2022\353\205\204/JY_Sam\354\235\230_\355\224\274\354\236\220\355\225\231\352\265\220.java" @@ -0,0 +1,214 @@ +import java.io.*; +import java.util.*; +public class JY_Sam의_피자학교 { + + static int N, K; + static int MX, MY, D; + static int[] arr; + static int[][] g; + // 상 우 하 좌 + static int[] dx = {-1, 0, 1, 0}; + static int[] dy = {0, 1, 0, -1}; + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + K = Integer.parseInt(st.nextToken()); + + st = new StringTokenizer(br.readLine()); + arr = new int[N]; + for(int i=0; i bottom) { + isStop = true; + break; + } + MX = i; + MY = j; + } + } + D = Math.max(N - (MX*MY), MX+1); + + } + public static void inputWheat() { + int minW = Integer.MAX_VALUE; + for(int i=0; i=0 && x=0 && y=0; i--) { + g[x][y] = arr[i]; + + // 다음 위치 + int nx = x+dx[dir]; + int ny = y+dy[dir]; + // 방향을 바꿔야 함 + if(!inRange(nx, ny, MX, MY) || g[nx][ny] != 0) { + dir = (dir+1)%4; + nx = x+dx[dir]; + ny = y+dy[dir]; + } + x = nx; + y = ny; + } + + // 나머지 바닥 도우 넣기 + x = MX; + y = 0; + for(int i=MX*MY; i g[nx][ny]) tmp[i][j] -= div; + else tmp[i][j] += div; + } + } + } + + for(int i=0; i=0; i--) { + if(g[i][j] == 0) continue; + trr[idx] = g[i][j]; + idx++; + } + } + + arr = trr; + } + public static void halfDough() { + int S = N / 4; + int dir = 1; // 우 -> + + int M = Math.max(S, 4); + g = new int[M][M]; + + // 맨 아래층 + int x = 3; + int y = 0; + for(int i=N-S; i { + int x, y, tCnt; + + public State(int x, int y, int tCnt) { + super(); + this.x = x; + this.y = y; + this.tCnt = tCnt; + } + @Override + public int compareTo(State other) { + if(this.tCnt == other.tCnt) { + if(this.x == other.x) { + return this.y - other.y; + } + return this.x - other.x; + } + return other.tCnt - this.tCnt; + } + + @Override + public String toString() { + return "State [x=" + x + ", y=" + y + ", tCnt=" + tCnt + "]"; + } + + } + + public static void main(String[] args) throws IOException { + // System.setIn(new FileInputStream("src/tree.txt")); + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + K = Integer.parseInt(st.nextToken()); + C = Integer.parseInt(st.nextToken()); + + // g: 나무 정보 + g = new int[N][N]; + // crr: 제초제 유효년도 정보 + crr = new int[N][N]; + for(int i=0; i> NOW: "+now); + // 1) 나무 성장 + growTree();; + + // 2) 번식 + breed(); + + // 3) 제초제 뿌리기 + ans += spread(); + + now++; + } + + System.out.println(ans); + + + } + public static void print(int[][] arr) { + for(int i=0; i=0 & x=0 && y oList = new ArrayList<>(); + for(int d=0; d<4; d++) { + int nx = x + dx[d]; + int ny = y + dy[d]; + if(!inRange(nx, ny)) continue; + // 벽 or 나무 + if(g[nx][ny] != 0) continue; + // 제초제 남아 있음 + if(crr[nx][ny] >= now) continue; + cnt++; + oList.add(new int[] {nx, ny}); + } + if(cnt == 0) continue; + int bTree = g[x][y] / cnt; + + // 나무 심기 + for(int[] next : oList) { + tmp[next[0]][next[1]] += bTree; + } + + } + } + + g = tmp; + + } + public static int spread() { + PriorityQueue pq = new PriorityQueue<>(); + + for(int x=0; x "+pq.peek()); + // 더이상 나무 없음 + if(pq.isEmpty()) { + return 0; + } + // 제초제 뿌릴 나무 선택 및 뿌리기 + State tree = pq.poll(); + g[tree.x][tree.y] = 0; + crr[tree.x][tree.y] = now + C; + for(int d=4; d<8; d++) { + for(int k=1; k 0) cnt++; + } + board[i][j] += cnt; + } + } + } + + private static void breeding() { + int[][] tmp = new int[N][N]; + + for (int x = 0; x < N; x++) { + for (int y = 0; y < N; y++) { + if (board[x][y] <= 0) continue; + int cnt = 0; + for (int i=0; i<4; i++) { // 번식 공간 카운트 + int nx = x + dx[i]; + int ny = y + dy[i]; + if (!isValid(nx, ny) || poison[nx][ny] > 0) continue; + if (board[nx][ny] == 0) cnt++; + } + + // 번식 + if (cnt==0) continue; + int nw = board[x][y] / cnt; + for (int i=0; i<4; i++) { // 주위로 나무 성장 + int nx = x + dx[i]; + int ny = y + dy[i]; + if (!isValid(nx, ny) || poison[nx][ny] > 0) continue; // 제초제 있는곳은 패쓰 + if (board[nx][ny]==0) tmp[nx][ny] += nw; + } + } + } + + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + board[i][j] += tmp[i][j]; + } + } + } + + private static void weeding() { + int mxVal = 0; + int mxx = 0; + int mxy = 0; + + for (int x = 0; x < N; x++) { + for (int y=0; y 0) { + board[mxx][mxy] = 0; + poison[mxx][mxy] = C; + for (int i=4; i<8; i++) { + for (int k = 1; k <= K; k++) { + int nx = mxx + dx[i]*k; + int ny = mxy + dy[i]*k; + if (!isValid(nx, ny) || board[nx][ny] < 0) continue; + if (board[nx][ny]==0) { + poison[nx][ny] = C; + break; + } + board[nx][ny] = 0; + poison[nx][ny] = 0; + } + } + } + } + + private static void disappear() { + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + if (poison[i][j] > 0) poison[i][j]--; + } + } + } + + private static boolean isValid(int x, int y) { + return 0<=x && x 0) { + grow(); + // System.out.println("1. "); + // System.out.println(Arrays.deepToString(board)); + + breeding(); + // System.out.println("2. "); + // System.out.println(Arrays.deepToString(board)); + + weeding(); + // System.out.println("3. "); + // System.out.println(Arrays.deepToString(board)); + // System.out.println(Arrays.deepToString(poison)); + + + disappear(); + // System.out.println("4. "); + // System.out.println(Arrays.deepToString(board)); + + } + System.out.println(ans); + } +} diff --git "a/CodeTree/2023-2024\353\205\204/JM_\352\263\240\353\214\200_\353\254\270\353\252\205_\354\234\240\354\240\201_\355\203\220\354\202\254.java" "b/CodeTree/2023-2024\353\205\204/JM_\352\263\240\353\214\200_\353\254\270\353\252\205_\354\234\240\354\240\201_\355\203\220\354\202\254.java" new file mode 100644 index 00000000..63969812 --- /dev/null +++ "b/CodeTree/2023-2024\353\205\204/JM_\352\263\240\353\214\200_\353\254\270\353\252\205_\354\234\240\354\240\201_\355\203\220\354\202\254.java" @@ -0,0 +1,166 @@ +import java.util.*; +import java.io.*; + +public class JM_고대_문명_유적_탐사 { + static int K; // 탐사 반복 횟수 + static int M; // 유물 조각의 개수 + static final int N = 5; + static int[][] map; + static int[] wall; + static int wallIdx; + static final int SIZE = 3; + static final int[][] DIR = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; + + private static boolean inRange(int y, int x) { + return 0 <= y && y < N && 0 <= x && x < N; + } + + private static int fillWallPiece(int[][] resultMap) { + int valueCount = 0; + for(int j = 0; j < N; j++){ + for(int i = N - 1; i >= 0; i--) { + if(resultMap[i][j] == 0) { + valueCount++; + resultMap[i][j] = wall[wallIdx]; + wallIdx = (wallIdx + 1) % M; + } + } + } + return valueCount; + } + + private static void remove(Queue pieces, int[][] currMap) { + while(!pieces.isEmpty()) { + int[] point = pieces.poll(); + currMap[point[0]][point[1]] = 0; + } + } + + private static Queue bfs(int sy, int sx, int[][] currMap, boolean[][] visited) { + Queue queue = new LinkedList<>(); + Queue piece = new LinkedList<>(); + + visited[sy][sx] = true; + queue.add(new int[] {sy, sx}); + piece.add(new int[] {sy, sx}); + + while(!queue.isEmpty()) { + int y = queue.peek()[0]; + int x = queue.peek()[1]; + queue.poll(); + + for(int i = 0; i < 4; i++) { + int ny = y + DIR[i][0]; + int nx = x + DIR[i][1]; + if(!inRange(ny, nx)) continue; + if(visited[ny][nx] || currMap[y][x] != currMap[ny][nx]) continue; + + visited[ny][nx] = true; + queue.add(new int[] {ny, nx}); + piece.add(new int[] {ny, nx}); + } + } + return piece; + } + + private static int calcValue(int[][] currMap) { + boolean[][] visited = new boolean[N][N]; + int count = 0; + for(int y = 0; y < N; y++) { + for(int x = 0; x < N; x++) { + if(visited[y][x]) continue; + + Queue pieces = bfs(y, x, currMap, visited); + if(pieces.size() >= SIZE) { + count += pieces.size(); + remove(pieces, currMap); + } + } + } + return count; + } + + private static int[][] rotate(int y, int x, int r) { + int[][] rotated = new int[SIZE][SIZE]; + for(int i = 0; i < SIZE; i++) { + for(int j = 0; j < SIZE; j++) { + if(r == 1) rotated[j][SIZE - i - 1] = map[y + i][x + j]; // 90도 + else if(r == 2) rotated[SIZE - i - 1][SIZE - j - 1] = map[y + i][x + j]; // 180도 + else rotated[SIZE - j - 1][i] = map[y + i][x + j]; // 270도 + } + } + + int[][] result = new int[N][N]; + for(int i = 0; i < N; i++) { + for(int j = 0; j < N; j++) { + if(y <= i && i <= y + 2 && x <= j && j <= x + 2) { + result[i][j] = rotated[i - y][j - x]; + } + else result[i][j] = map[i][j]; + } + } + return result; + } + + private static int[][] process() { + int maxValue = 0; + int[][] maxMap = new int[N][N]; + maxMap[0][0] = -1; + + for(int r = 1; r <= 3; r++) { + for(int j = 0; j < SIZE; j++) { + for(int i = 0; i < SIZE; i++) { + int[][] currMap = rotate(i, j, r); + int value = calcValue(currMap); + if(maxValue < value) { + maxValue = value; + maxMap = currMap; + } + } + } + } + return maxMap; + } + + + private static String solve() { + StringBuilder sb = new StringBuilder(); + while(K-- > 0) { + int[][] resultMap = process(); // 1. 탐사 진행 + if(resultMap[0][0] == -1) break; // 유물 획득 실패 + + int value = fillWallPiece(resultMap); // 2. 유물 획득 + + while(calcValue(resultMap) != 0) { // 3. 연쇄 획득 + value += fillWallPiece(resultMap); + } + + map = resultMap; + sb.append(value).append(" "); + } + return sb.toString(); + } + + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + K = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + + map = new int[N][N]; + for(int i = 0; i < N; i++) { + st = new StringTokenizer(br.readLine()); + for(int j = 0; j < N; j++) { + map[i][j] = Integer.parseInt(st.nextToken()); + } + } + + wall = new int[M]; + st = new StringTokenizer(br.readLine()); + for(int i = 0; i < M; i++) { + wall[i] = Integer.parseInt(st.nextToken()); + } + + System.out.println(solve()); + } +} diff --git "a/CodeTree/2023-2024\353\205\204/JM_\354\275\224\353\223\234\355\212\270\353\246\254_\353\251\224\354\213\240\354\240\200" "b/CodeTree/2023-2024\353\205\204/JM_\354\275\224\353\223\234\355\212\270\353\246\254_\353\251\224\354\213\240\354\240\200" new file mode 100644 index 00000000..d6e952b3 --- /dev/null +++ "b/CodeTree/2023-2024\353\205\204/JM_\354\275\224\353\223\234\355\212\270\353\246\254_\353\251\224\354\213\240\354\240\200" @@ -0,0 +1,176 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Arrays; +import java.util.StringTokenizer; + +public class JM_코드트리_메신저 { + static class Room { + int c; + boolean alert; + int authority; + + int parent; + int leftChild; + int rightChild; + + int[] effect; + + public Room(int c) { + this.c = c; + this.alert = true; + this.parent = -1; + this.leftChild = -1; + this.rightChild = -1; + this.effect = new int[DEPTH + 1]; + } + + public void toggleAlert() { + this.alert = !this.alert; + } + } + static int N; + static int Q; + static Room[] rooms; + static final int DEPTH = 20; + + private static void update(int c) { + while (c != 0) { + Room curr = rooms[c]; + Arrays.fill(curr.effect, 0); + for (int i = 0; i <= curr.authority; i++) { + rooms[c].effect[i]++; + } + + if(curr.leftChild != -1 && rooms[curr.leftChild].alert) { + for (int i = 1; i <= DEPTH; i++) { + curr.effect[i - 1] += rooms[curr.leftChild].effect[i]; + } + } + + if(curr.rightChild != -1 && rooms[curr.rightChild].alert) { + for (int i = 1; i <= DEPTH; i++) { + curr.effect[i - 1] += rooms[curr.rightChild].effect[i]; + } + } + + c = rooms[c].parent; + } + } + + private static void swapParent(int c1, int c2) { + int p1 = rooms[c1].parent; + int p2 = rooms[c2].parent; + + if(rooms[p1].leftChild == c1) { + rooms[p1].leftChild = c2; + } else if(rooms[p1].rightChild == c1) { + rooms[p1].rightChild = c2; + } + + if(rooms[p2].leftChild == c2) { + rooms[p2].leftChild = c1; + } else if(rooms[p2].rightChild == c2) { + rooms[p2].rightChild = c1; + } + + rooms[c1].parent = p2; + rooms[c2].parent = p1; + + update(c1); + update(c2); + } + + private static void changeAuthority(int c, int power) { + rooms[c].authority = power > DEPTH ? DEPTH : power; + update(c); + } + + private static void toggleNotification(int c) { + rooms[c].toggleAlert(); + update(c); + } + + private static void initEffect(int c) { + if(c == -1) return; + + Room curr = rooms[c]; + for (int i = 0; i <= curr.authority; i++) { + rooms[c].effect[i]++; + } + + initEffect(curr.leftChild); + initEffect(curr.rightChild); + + if(curr.leftChild != -1) { + for (int i = 1; i <= DEPTH; i++) { + curr.effect[i - 1] += rooms[curr.leftChild].effect[i]; + } + } + + if(curr.rightChild != -1) { + for (int i = 1; i <= DEPTH; i++) { + curr.effect[i - 1] += rooms[curr.rightChild].effect[i]; + } + } + } + + private static void init(StringTokenizer st) { + rooms = new Room[N + 1]; + for (int i = 0; i <= N; i++) { + rooms[i] = new Room(i); + } + + for (int i = 1; i <= N; i++) { + int pIdx = Integer.parseInt(st.nextToken()); + rooms[i].parent = pIdx; + if(rooms[pIdx].leftChild == -1) rooms[pIdx].leftChild = i; + else rooms[pIdx].rightChild = i; + } + + for (int i = 1; i <= N; i++) { + rooms[i].authority = Integer.parseInt(st.nextToken()); + if(rooms[i].authority > DEPTH) rooms[i].authority = DEPTH; + } + + initEffect(0); + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + N = Integer.parseInt(st.nextToken()); + Q = Integer.parseInt(st.nextToken()); + + StringBuilder sb = new StringBuilder(); + int c; + while (Q-- > 0) { + st = new StringTokenizer(br.readLine()); + int command = Integer.parseInt(st.nextToken()); + switch (command) { + case 100: // 사내 메신저 준비 + init(st); + break; + case 200: // 알림망 설정 (ON/OFF) + c = Integer.parseInt(st.nextToken()); + toggleNotification(c); + break; + case 300: // 권한 세기 변경 + c = Integer.parseInt(st.nextToken()); + int power = Integer.parseInt(st.nextToken()); + changeAuthority(c, power); + break; + case 400: // 부모 채팅방 교환 + int c1 = Integer.parseInt(st.nextToken()); + int c2 = Integer.parseInt(st.nextToken()); + swapParent(c1, c2); + break; + case 500: // 알림을 받을 수 있는 채팅방 수 조회 + c = Integer.parseInt(st.nextToken()); + sb.append(rooms[c].effect[0] - 1).append("\n"); + break; + } + } + System.out.println(sb); + } +} diff --git "a/CodeTree/2023-2024\353\205\204/JM_\354\275\224\353\223\234\355\212\270\353\246\254_\354\230\244\353\247\210\354\271\264\354\204\270.java" "b/CodeTree/2023-2024\353\205\204/JM_\354\275\224\353\223\234\355\212\270\353\246\254_\354\230\244\353\247\210\354\271\264\354\204\270.java" new file mode 100644 index 00000000..48295bce --- /dev/null +++ "b/CodeTree/2023-2024\353\205\204/JM_\354\275\224\353\223\234\355\212\270\353\246\254_\354\230\244\353\247\210\354\271\264\354\204\270.java" @@ -0,0 +1,160 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; + +/** + * 28%에서 틀렸던 이유: 사람이 나가는 시간을 MAX로 Update 안해줌 + */ +public class JM_코드트리_오마카세 { + static class Sushi { + int time; + int pos; + String name; + + public Sushi(int time, int pos, String name) { + this.time = time; + this.pos = pos; + this.name = name; + } + } + static class Person { + int time; + int pos; + String name; + int n; + int maxOutTime; + public Person(int time, int pos, String name, int n) { + this.time = time; + this.pos = pos; + this.name = name; + this.n = n; + } + } + static class Time implements Comparable