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_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/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); + } +}