diff --git "a/BOJ/1000-5000\353\262\210/HW_1194.java" "b/BOJ/1000-5000\353\262\210/HW_1194.java" new file mode 100644 index 00000000..5e7b8c2e --- /dev/null +++ "b/BOJ/1000-5000\353\262\210/HW_1194.java" @@ -0,0 +1,87 @@ +import java.util.*; +import java.io.*; + +// 미로를 탈출하는데 드는 이동 횟수의 최솟값을 출력 + +public class HW_1194 { + static int N, M; + static char[][] board; + static boolean[][][] visited; // 방문 + static int[] dx = {0, 1, 0, -1}; + static int[] dy = {1, 0, -1, 0}; + static class Node{ + int x, y, key, step; + public Node(int x, int y, int key, int step) { + this.x = x; + this.y = y; + this.key = key; + this.step = step; + } + } + + 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]; + visited = new boolean[N][M][64]; + + int startX = 0, startY = 0; + for(int i=0; i queue = new LinkedList<>(); + queue.add(new Node(x, y, 0, 0)); + visited[x][y][0] = true; + board[x][y] = '.'; // 빈칸: 이동 가능 + + while(!queue.isEmpty()){ + Node cur = queue.poll(); + if(board[cur.x][cur.y]=='1'){ + return cur.step; + } + for(int i=0; i<4; i++){ + int nx = cur.x + dx[i]; + int ny = cur.y + dy[i]; + int nkey = cur.key; + + if(!isValid(nx,ny) || visited[nx][ny][nkey] || board[nx][ny]=='#') { + continue; + } + + if ('a' <= board[nx][ny] && board[nx][ny] <= 'f') { + nkey |= (1 << (board[nx][ny] - 'a')); // 새로운 열쇠 획득 + } + + if ('A' <= board[nx][ny]&& board[nx][ny] <= 'F') { + if ((nkey & (1 << (board[nx][ny] - 'A'))) == 0) { + continue; // 열쇠 없으면 이동 불가 + } + } + + if (!visited[nx][ny][nkey]) { // 새 열쇠 상태로 방문 + queue.add(new Node(nx, ny, nkey, cur.step + 1)); + visited[nx][ny][nkey] = true; + } + } + } + return -1; + } + static boolean isValid(int nx, int ny){ + return 0<=nx && nx board[K][0]){ + rnk++; + } else if(board[i][0] == board[K][0] && board[i][1] > board[K][1]){ + rnk++; + } else if(board[i][0] == board[K][0] && board[i][1] == board[K][1] &&board[i][2] > board[K][2]){ + rnk++; + } + } + + System.out.println(rnk); + } +} \ No newline at end of file diff --git "a/CodeTree/2019-2020\353\205\204/HW_\354\210\240\353\236\230\354\236\241\352\270\260_\354\262\264\354\212\244.java" "b/CodeTree/2019-2020\353\205\204/HW_\354\210\240\353\236\230\354\236\241\352\270\260_\354\262\264\354\212\244.java" new file mode 100644 index 00000000..b1337aae --- /dev/null +++ "b/CodeTree/2019-2020\353\205\204/HW_\354\210\240\353\236\230\354\236\241\352\270\260_\354\262\264\354\212\244.java" @@ -0,0 +1,119 @@ +import java.util.*; +import java.io.*; + +public class HW_술래잡기_체스 { + static int[] dx = {-1, -1, 0, 1, 1, 1, 0, -1}; + static int[] dy = {0, -1, -1, -1, 0, 1, 1, 1}; + static int ans = 0; + + static class Node { + int p, d; + Node(int p, int d) { + this.p = p; + this.d = d; + } + } + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st; + + Node[][] board = new Node[4][4]; + for (int i = 0; i < 4; i++) { + st = new StringTokenizer(br.readLine()); + for (int j = 0; j < 4; j++) { + int p = Integer.parseInt(st.nextToken()); + int d = Integer.parseInt(st.nextToken()) - 1; + board[i][j] = new Node(p, d); + } + } + + int initScore = board[0][0].p; + int initDir = board[0][0].d; + + board[0][0] = new Node(0, initDir); // 술래말 초기화 + + dfs(board, 0, 0, initScore); + System.out.println(ans); + } + + static void dfs(Node[][] board, int x, int y, int score) { + ans = Math.max(ans, score); // 점수 갱신 + + Node[][] copyBoard = copy(board); + find(copyBoard); + + Node cur = copyBoard[x][y]; + int dir = cur.d; + + int nx = x + dx[dir]; + int ny = y + dy[dir]; + + // 도둑말 이동 + while (isValid(nx, ny)) { + if (copyBoard[nx][ny] != null) { // 도둑말이 있는 칸만 이동 + Node caught = copyBoard[nx][ny]; + copyBoard[x][y] = null; // 술래말이 원래 있던 칸 비우기 + copyBoard[nx][ny] = new Node(0, caught.d); // 술래말 이동 + + dfs(copyBoard, nx, ny, score + caught.p); // 재귀 + + copyBoard[nx][ny] = caught; + copyBoard[x][y] = cur; + } + nx += dx[dir]; + ny += dy[dir]; + } + } + + static void find(Node[][] board) { + for (int k = 1; k <= 16; k++) { // 도둑말 번호 순서대로 탐색 + boolean visited = false; // 방문 처리 + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + if (board[i][j] != null && board[i][j].p == k) { + move(board, i, j); + visited = true; + break; + } + } + if(visited) break; + } + } + } + + static void move(Node[][] board, int x, int y) { + Node cur = board[x][y]; + int d = cur.d; + + for (int i = 0; i < 8; i++) { + int nx = x + dx[d]; + int ny = y + dy[d]; + + // 술래말이 있는 칸이나 경계를 벗어나면 이동 불가 + if (isValid(nx, ny) && (board[nx][ny] == null || board[nx][ny].p != 0)) { + Node temp = board[nx][ny]; + board[nx][ny] = new Node(cur.p, d); // 새 위치로 이동 + board[x][y] = temp; // 기존 위치 업데이트 + return; + } + d = (d + 1) % 8; // 반시계 방향 45도 회전 + } + } + + static boolean isValid(int nx, int ny) { + return 0 <= nx && nx < 4 && 0 <= ny && ny < 4; + } + + static Node[][] copy(Node[][] board) { + Node[][] tempBoard = new Node[4][4]; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + if (board[i][j] != null) { + tempBoard[i][j] = new Node(board[i][j].p, board[i][j].d); + } + } + } + return tempBoard; + } +} diff --git a/Programmers/Level2/HW_250135.java b/Programmers/Level2/HW_250135.java new file mode 100644 index 00000000..00189308 --- /dev/null +++ b/Programmers/Level2/HW_250135.java @@ -0,0 +1,47 @@ +class HW_250135 { + public int solution(int h1, int m1, int s1, int h2, int m2, int s2) { + int cnt = 0; + + double start = h1 * 3600 + m1 * 60 + s1; + double end = h2 * 3600 + m2 * 60 + s2; + + int halfDay = 12 * 3600; + if (start == 0 || start == halfDay) + cnt++; + + while (start < end) { + double h = (start / 120) % 360; // 시침 + double m = (start / 10) % 360; // 분침 + double s = (start * 6) % 360; // 초침 + + // 다음 시간의 각도 계산 + double nextH = ((start + 1) / 120) % 360; + double nextM = ((start + 1) / 10) % 360; + double nextS = ((start + 1) * 6) % 360; + + // 360도 -> 0도 + if (nextH == 0.0) { + nextH = 360.0; + } + if (nextM == 0.0){ + nextM = 360.0; + } + + if (nextS == 0.0) { + nextS = 360.0; + } + + if (s < h && nextH <= nextS) // 초침 == 시침 + cnt++; + + if (s < m && nextM <= nextS) // 초침==분침 + cnt++; + + if (nextH == nextS && nextM == nextS) // 시침,분침==초침 + cnt--; + + start++; + } + return cnt; + } +} \ No newline at end of file diff --git a/Programmers/Level3/HW_150367.java b/Programmers/Level3/HW_150367.java new file mode 100644 index 00000000..3bd0b5a0 --- /dev/null +++ b/Programmers/Level3/HW_150367.java @@ -0,0 +1,62 @@ +import java.util.*; + +class HW_150367 { + public int[] solution(long[] numbers) { + int[] result = new int[numbers.length]; + + for (int i = 0; i < numbers.length; i++) { + String binary = Long.toBinaryString(numbers[i]); // 숫자를 이진수로 변환 + String fullBinary = extend(binary); // 포화 이진트리로 확장 + result[i] = isValidTree(fullBinary) ? 1 : 0; // 트리 검증 + } + return result; + } + + // 이진수를 포화 이진트리 형태로 확장 + private String extend(String binary) { + int length = binary.length(); + int height = 0; + + // 포화 이진트리의 노드 개수 계산 + while ((1 << height) - 1 < length) { + height++; + } + + int fullLength = (1 << height) - 1; // 포화 이진트리 노드 개수 + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < fullLength - length; i++) { + sb.append("0"); // 앞쪽에 더미 노드 추가 + } + sb.append(binary); + return sb.toString(); + } + + // 트리 검증 + private boolean isValidTree(String binary) { + return isValidSubtree(binary, 0, binary.length() - 1); + } + + // 서브트리 검증 + private boolean isValidSubtree(String binary, int start, int end) { + if (start > end) { // 범위를 벗어나면 유효함 + return true; + } + + int mid = (start + end) / 2; // 현재 루트 노드 + char root = binary.charAt(mid); + + // 왼쪽과 오른쪽 서브트리 + boolean leftValid = isValidSubtree(binary, start, mid - 1); + boolean rightValid = isValidSubtree(binary, mid + 1, end); + + // 루트가 0인데 자식이 1인 경우 규칙 위반 + if (root == '0') { + for (int i = start; i <= end; i++) { + if (binary.charAt(i) == '1') { + return false; + } + } + } + return leftValid && rightValid; // 왼쪽, 오른쪽 서브트리 모두 유효 -> 전체 트리 유효 + } +} \ No newline at end of file diff --git "a/SQL/13\354\243\274\354\260\250/HW_Game Play Analysis IV.sql" "b/SQL/13\354\243\274\354\260\250/HW_Game Play Analysis IV.sql" new file mode 100644 index 00000000..786cf605 --- /dev/null +++ "b/SQL/13\354\243\274\354\260\250/HW_Game Play Analysis IV.sql" @@ -0,0 +1,6 @@ +SELECT ROUND(COUNT(DISTINCT player_id) / (SELECT COUNT(DISTINCT player_id) FROM Activity), 2) AS fraction +FROM Activity +WHERE (player_id, DATE_SUB(event_date, INTERVAL 1 DAY)) + IN (SELECT player_id, MIN(event_date) AS first_login + FROM Activity + GROUP BY player_id); \ No newline at end of file diff --git "a/SQL/13\354\243\274\354\260\250/HW_\354\227\205\352\267\270\353\240\210\354\235\264\353\223\234 \355\225\240 \354\210\230 \354\227\206\353\212\224 \354\225\204\354\235\264\355\205\234 \352\265\254\355\225\230\352\270\260.sql" "b/SQL/13\354\243\274\354\260\250/HW_\354\227\205\352\267\270\353\240\210\354\235\264\353\223\234 \355\225\240 \354\210\230 \354\227\206\353\212\224 \354\225\204\354\235\264\355\205\234 \352\265\254\355\225\230\352\270\260.sql" new file mode 100644 index 00000000..4bba3e43 --- /dev/null +++ "b/SQL/13\354\243\274\354\260\250/HW_\354\227\205\352\267\270\353\240\210\354\235\264\353\223\234 \355\225\240 \354\210\230 \354\227\206\353\212\224 \354\225\204\354\235\264\355\205\234 \352\265\254\355\225\230\352\270\260.sql" @@ -0,0 +1,8 @@ +-- 업그레이드 할 수 없는 아이템 찾기 +-- A 아이템이 B아이템을 부모로 가지지 않아야함 +-- ITEM_ID != PARENT_ITEM_ID 행 찾기 +SELECT i.ITEM_ID, i.ITEM_NAME, i.RARITY +FROM ITEM_INFO i + LEFT JOIN ITEM_TREE t ON i.ITEM_ID = t.PARENT_ITEM_ID +WHERE t.PARENT_ITEM_ID IS NULL +ORDER BY i.ITEM_ID DESC; \ No newline at end of file