diff --git "a/BOJ/1000-5000353円262円210円/DH_2629.java" "b/BOJ/1000-5000353円262円210円/DH_2629.java" new file mode 100644 index 00000000..3f65d5cd --- /dev/null +++ "b/BOJ/1000-5000353円262円210円/DH_2629.java" @@ -0,0 +1,64 @@ +import java.io.*; +import java.util.*; + +/* + * 양팔저울 + */ + +public class DH_2629 { + static final int LIMIT = 15_000; // 추를 통해 알 수 있는 최대 무게 + static int N, M; + static int[] arr; + static boolean[][] dp; // [idx][weight]: idx번째 추까지 고려했을 때, weight 무게를 만들 수 있는지 + static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + static StringTokenizer st; + + public static void main(String[] args) throws Exception { + initInput(); + solution(); + } + + static void solution() throws Exception { + StringBuilder sb = new StringBuilder(); + + dp = new boolean[N + 1][LIMIT + 1]; + + getPossibleWeight(0, 0); + + st = new StringTokenizer(br.readLine()); + + for(int i = 0; i < M; i++) { + + int num = Integer.parseInt(st.nextToken()); + + // 제한 무게를 넘거나, 모든 구슬을 확인했을 때 num무게를 만들 수 없다면 N출력 + if(num> LIMIT || !dp[N][num]) sb.append("N "); + // 가능하다면 Y 출력 + else sb.append("Y "); + } + + System.out.println(sb); + } + + static void getPossibleWeight(int idx, int weight) { + if(dp[idx][weight]) return; + dp[idx][weight] = true; + + if(idx == N) return; + + getPossibleWeight(idx + 1, weight + arr[idx]); // 현재 기준이 되는 저울에 올리기 + getPossibleWeight(idx + 1, weight); // 넘어가기 + getPossibleWeight(idx + 1, Math.abs(weight - arr[idx])); // 반대 저울에 올리기 + } + + static void initInput() throws Exception { + + N = Integer.parseInt(br.readLine()); // 추의 개수 + arr = new int[N]; + + st = new StringTokenizer(br.readLine()); + for(int i = 0; i < arr.length; i++) arr[i] = Integer.parseInt(st.nextToken()); + + M = Integer.parseInt(br.readLine()); + } +} \ No newline at end of file diff --git "a/BOJ/20001-25000353円262円210円/DH_21758.java" "b/BOJ/20001-25000353円262円210円/DH_21758.java" new file mode 100644 index 00000000..84946fe8 --- /dev/null +++ "b/BOJ/20001-25000353円262円210円/DH_21758.java" @@ -0,0 +1,63 @@ +import java.io.*; +import java.util.*; + +/* + * 꿀 따기 + */ + +public class DH_21758 { + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + int N = Integer.parseInt(br.readLine()); + + StringTokenizer st = new StringTokenizer(br.readLine()); + + // arr, S1: 왼쪽에서 오른쪽으로 움직일 때 사용 + int[] arr = new int[N]; + for(int i = 0; i < arr.length; i++) arr[i] = Integer.parseInt(st.nextToken()); + + // tmp, S2: 오른쪽에서 왼쪽으로 움직일 때 사용 (arr를 뒤집어줌) + int[] tmp = new int[N]; + for(int i = 0; i < N; i++) tmp[i] = arr[N - 1 - i]; + + // 누적합 구하기 + int[] S1 = new int[N + 1], S2 = new int[N + 1]; + for(int i = 1; i < N + 1; i++) { + S1[i] = S1[i - 1] + arr[i - 1]; + S2[i] = S2[i - 1] + tmp[i - 1]; + } + + int result = 0; + result = Math.max(result, getHoney(S1, arr, N)); + result = Math.max(result, getHoney(S2, tmp, N)); + + System.out.println(result); + } + + // 꿀벌들이 얻을 수 있는 꿀의 최대값 구하기 + static int getHoney(int[] S, int[] arr, int N) { + int bee1 = 0, result = 0; + + // 첫 번째 꿀벌이 얻을 수 있는 꿀의 양 + int getBee1 = S[N] - S[bee1] - arr[bee1]; + + // '꿀벌 - 꿀벌 - 꿀' 일 때 + for(int bee2 = 1; bee2 < N - 1; bee2++) { + int tmpGetBee1 = getBee1 - arr[bee2]; // 다른 꿀벌이 있는 위치의 꿀은 못얻음 + + // 두 번째 꿀벌이 얻ᄋ르 수 있는 꿀의 양 + int getBee2 = S[N] - S[bee2] - arr[bee2]; + result = Math.max(result, tmpGetBee1 + getBee2); + } + + // '꿀벌 - 꿀 - 꿀벌' 일 때 + for(int honey = 1; honey < N - 1; honey++) { + int tmpGetBee1 = S[honey + 1] - S[bee1] - arr[bee1]; // 다른 꿀벌이 있는 위치의 꿀은 못얻음 + int getBee2 = S[N] - S[honey] - arr[N - 1]; + + result = Math.max(result, tmpGetBee1 + getBee2); + } + + return result; + } +} diff --git "a/BOJ/30000-35000353円262円210円/DH_30407.java" "b/BOJ/30000-35000353円262円210円/DH_30407.java" new file mode 100644 index 00000000..ce386fc4 --- /dev/null +++ "b/BOJ/30000-35000353円262円210円/DH_30407.java" @@ -0,0 +1,73 @@ +import java.io.*; +import java.util.*; + +/* + * 나비의 간식을 훔쳐먹은 춘배 + */ + +public class DH_30407 { + static int N, H, D, K, result; + static int[] R; + + public static void main(String[] args) throws Exception { + initInput(); + + // 깜짝 놀라게 하는 경우가 없을 때 + powerset(0, H, D, -2); + + // i 번째에 깜짝 놀라게 하기 시전 + for(int i = 0; i < N; i++) powerset(0, H, D, i); + + if(result <= 0) System.out.println(-1); + else System.out.println(result); + } + + static void powerset(int depth, int h, int dis, int surprised) { + if(depth == N) { + result = Math.max(result, h); + return; + } + + if(h <= 0 || h < result) return; + + //깜짝 놀라게 하기 + if(surprised == depth) { + int punchPower = Math.max(0, R[depth] - dis); + powerset(depth + 1, h - punchPower, dis, surprised); + } else { + + // 웅크리기 ------------------------------------------ + int punchPower = 0; // 나비의 펀치 세기 + + if(surprised + 1 == depth) punchPower = 0; // 깜짝 놀라게 하기 다음 턴의 경우 나비의 행동 무시함 + else punchPower = Math.max(0, (R[depth] - dis) / 2); + + powerset(depth + 1, h - punchPower, dis, surprised); + + // 네발로 걷기 ------------------------------------------ + int nextDis = dis + K; + + if(surprised + 1 == depth) punchPower = 0; // 깜짝 놀라게 하기 다음 턴의 경우 나비의 행동 무시함 + else punchPower = Math.max(0, R[depth] - nextDis); + + powerset(depth + 1, h - punchPower, nextDis, surprised); + } + } + + static void initInput() throws Exception { + 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()); // 네발로 걷기 시 이동하는 거리 + + R = new int[N]; + + for(int i = 0; i < N; i++) R[i] = Integer.parseInt(br.readLine()); + } +} diff --git "a/CodeTree/2023-2024353円205円204円/DH_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-2024353円205円204円/DH_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..5394ba17 --- /dev/null +++ "b/CodeTree/2023-2024353円205円204円/DH_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,152 @@ +import java.io.*; +import java.util.*; + +/* + * 초밥 회전 시스템을 구현을 통해 관리하면 매우 복잡해짐 + * + * 주방장이 만든 초밥이 손님에게 도달하는 시간을 계산한 뒤, 사라지는 시간 + * 손님들이 초밥을 다 먹고 떠나는 시간을 계산하여 쿼리에 추가 + * + * 초밥과 손님의 입장과 퇴장을 쿼리로 표현하여 시간 순으로 처리... + * 모든 행동들이 시간 순으로 일어나기 때문에, 이렇게 구현하면 된다고 한다..! + */ + +public class DH_코드트리_오마카세 { + static class Query implements Comparable { + int cmd, t, x, n; + String name; + + public Query(int cmd, int t, int x, int n, String name) { + this.cmd = cmd; + this.t = t; + this.x = x; + this.n = n; + this.name = name; + } + + @Override + public int compareTo(Query o) { + if(this.t != o.t) return Integer.compare(this.t, o.t); // 시간 순 + return Integer.compare(this.cmd, o.cmd); // 명령순 + } + } + static class Time { + int in, out; + + public Time(int in) { + this.in = in; + } + + public void setOutTime(int time) { + this.out = Math.max(time, this.out); + } + + } + static int L, Q; + + // 쿼리가 시간 순으로 입력될 수 있도록 함 + static ArrayList query = new ArrayList(); + static HashSet people = new HashSet(); // 등장한 사람 목록 관리 + static HashMap> pQuery = new HashMap(); // 사람들마다 쿼리를 관리함 + static HashMap pos = new HashMap(); // 사람들마다 위치 관리 + static HashMap time = new HashMap(); // 사람들의 출입 시간 관리 + static StringBuilder sb = new StringBuilder(); + + public static void main(String[] args) throws Exception { + System.setIn(new FileInputStream("./input/코드트리오마카세.txt")); + + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + L = Integer.parseInt(st.nextToken()); + Q = Integer.parseInt(st.nextToken()); + + for(int q = 0; q < Q; q++) { + + st = new StringTokenizer(br.readLine()); + + int cmd = Integer.parseInt(st.nextToken()); + int t = 0, x = 0, n = 0; + String name = null; + + if(cmd == 100) { + t = Integer.parseInt(st.nextToken()); + x = Integer.parseInt(st.nextToken()); + name = st.nextToken(); + + if(pQuery.get(name) == null) pQuery.put(name, new PriorityQueue()); + pQuery.get(name).add(new Query(cmd, t, x, n, name)); + } + + if(cmd == 200) { + t = Integer.parseInt(st.nextToken()); + x = Integer.parseInt(st.nextToken()); + name = st.nextToken(); + n = Integer.parseInt(st.nextToken()); + + people.add(name); + + time.put(name, new Time(t)); + pos.put(name, x); + } + + if(cmd == 300) { + t = Integer.parseInt(st.nextToken()); + } + + query.add(new Query(cmd, t, x, n, name)); + } + + // 각 사람마다 자신의 이름이 적힌 초밥을 언제 먹게 되는지 계산하고, 기존 쿼리에 추가 + for(String p: people) { + + // 마지막으로 먹는 초밥 중 가장 늦은 시간이 됨! + while(!pQuery.get(p).isEmpty()) { + Query current = pQuery.get(p).poll(); + + int removeTime = 0; // 사람이 나가게 되는 시간 + + // 초밥 - 사람 + // 초밥이 사람이 등장하기 전에 미리 주어진 상황 + if(current.t < time.get(p).in) { + + // 사람이 들어왔을 때, 초밥의 위치 + int sushiPos = (current.x + (time.get(p).in - current.t)) % L; + int addTime = (pos.get(p) - sushiPos + L) % L; + + removeTime = time.get(p).in + addTime; + } + + // 사람 - 초밥 + else { + int addTime = (pos.get(p) - current.x + L) % L; + removeTime = current.t + addTime; + } + + time.get(p).setOutTime(removeTime); // 나가는 시간을 제일 마지막 초밥을 먹는 시간으로 설정해야 됨 + + // 초밥이 사라지는 쿼리 추가 + query.add(new Query(111, removeTime, 0, 0, p)); + } + } + + // 사람들이 나가는 쿼리 추가 + for(String p: people) query.add(new Query(222, time.get(p).out, 0, 0, p)); + + Collections.sort(query); + + int sushiCnt = 0, peopleCnt = 0; + + for(Query current: query) { + + if(current.cmd == 100) sushiCnt++; // 초밥이 생겼다가 + else if(current.cmd == 111) sushiCnt--; // 초밥을 먹었다가 + else if(current.cmd == 200) peopleCnt++; // 사람이 들어왔다가 + else if(current.cmd == 222) peopleCnt--; // 사람이 나갔다가 + else sb.append(peopleCnt).append(" ").append(sushiCnt).append("\n"); + } + + System.out.println(sb); + } + +} \ No newline at end of file diff --git a/Programmers/Level2/DH_148652.java b/Programmers/Level2/DH_148652.java new file mode 100644 index 00000000..dd7bc873 --- /dev/null +++ b/Programmers/Level2/DH_148652.java @@ -0,0 +1,32 @@ +/* + * 유사 칸토어 비트열 + */ + +public class DH_148652 { + static long solution(int n, long l, long r) { + return getOneCnt(r, n) - getOneCnt(l - 1, n); + } + + static long getOneCnt(long e, int depth) { + if(depth == 0) return 1; // 0번째 비트열: 1 + + long digit = (long) Math.pow(5, depth - 1); // depth번째에서 한 그룹당 몇 개의 자릿수를 가지고 있는지 + + // e가 속하는 구간이 어디인지 구하기 (0, 1, 2, 3, 4) + int area = (int) (e / digit); + if(e % digit == 0) area -= 1; // 구간 경계에 있는거 올바른 구간에 포함될 수 있도록 -1 해주기 + + int prevOneCnt = (int) Math.pow(4, depth - 1); + + // 0기준 왼쪽 (1인 구역의 개수가 전체 자리수)개 + if(area < 2) return prevOneCnt * area + getOneCnt(e - (digit * area), depth - 1); + // 0있는 부분 + else if(area == 2) return prevOneCnt * area; + // 0기준 오른쪽 (1인 구역의 개수가 전체 자리수 - 1)개 + return prevOneCnt * (area - 1) + getOneCnt(e - (digit * area), depth - 1); + } + public static void main(String[] args) { + int n = 2, l = 4, r = 17; + System.out.println(solution(n, l, r)); + } +} diff --git "a/SQL/24354円243円274円354円260円250円/353円251円270円354円242円205円354円234円204円352円270円260円354円235円230円 353円214円200円354円236円245円352円267円240円 354円260円276円352円270円260円.sql" "b/SQL/24354円243円274円354円260円250円/353円251円270円354円242円205円354円234円204円352円270円260円354円235円230円 353円214円200円354円236円245円352円267円240円 354円260円276円352円270円260円.sql" new file mode 100644 index 00000000..f0fbf8f2 --- /dev/null +++ "b/SQL/24354円243円274円354円260円250円/353円251円270円354円242円205円354円234円204円352円270円260円354円235円230円 353円214円200円354円236円245円352円267円240円 354円260円276円352円270円260円.sql" @@ -0,0 +1,21 @@ +WITH recursive CTE AS ( + SELECT id, parent_id, 1 as GENERATION + FROM ECOLI_DATA + WHERE PARENT_ID IS NULL + + UNION ALL + + SELECT b.id, b.parent_id, a.generation + 1 + FROM CTE a + JOIN ECOLI_DATA b ON a.id = b.parent_id +) + +SELECT COUNT(a.ID) as COUNT, a.GENERATION +FROM CTE a +WHERE ID NOT IN ( + SELECT DISTINCT PARENT_ID + FROM CTE + WHERE PARENT_ID IS NOT NULL + ) +GROUP BY a.GENERATION +ORDER BY a.GENERATION \ No newline at end of file

AltStyle によって変換されたページ (->オリジナル) /