diff --git "a/BOJ/20001-25000353円262円210円/SB_20181.java" "b/BOJ/20001-25000353円262円210円/SB_20181.java" new file mode 100644 index 00000000..cc71b4ac --- /dev/null +++ "b/BOJ/20001-25000353円262円210円/SB_20181.java" @@ -0,0 +1,40 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Arrays; +import java.util.StringTokenizer; + +public class SB_20181 { + static int N, K; + static int[] arr; + 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()); + + arr = new int[N]; + st = new StringTokenizer(br.readLine()); + for (int i = 0; i < N; i++) { + arr[i] = Integer.parseInt(st.nextToken()); + } + + long[] dp = new long[N + 1]; + + long happy = 0; + int left = 0; + for (int right = 0; right < N; right++) { + happy += arr[right]; + + while (happy>= K) { + dp[right + 1] = Math.max(dp[right + 1], dp[left] + happy - K); // dp[left]는 이전 구간의 최대값(이전 최종 right의 위치) + happy -= arr[left++]; + } + + dp[right + 1] = Math.max(dp[right], dp[right + 1]); // 현재까지의 최대값과 갱신된 최대값 비교 + } + + System.out.println(Arrays.toString(dp)); + } +} diff --git "a/BOJ/20001-25000353円262円210円/SB_20291.java" "b/BOJ/20001-25000353円262円210円/SB_20291.java" new file mode 100644 index 00000000..94e6d852 --- /dev/null +++ "b/BOJ/20001-25000353円262円210円/SB_20291.java" @@ -0,0 +1,28 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.TreeMap; + +public class SB_20291 { + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st; + StringBuilder sb = new StringBuilder(); + int N = Integer.parseInt(br.readLine()); + + TreeMap map = new TreeMap(); + for (int i = 0; i < N; i++) { + st = new StringTokenizer(br.readLine(), "."); + String name = st.nextToken(); + String ext = st.nextToken(); + map.put(ext, map.getOrDefault(ext, 0) + 1); + } + + for (Map.Entry entry : map.entrySet()) { + sb.append(entry.getKey()).append(" ").append(entry.getValue()).append('\n'); + } + System.out.println(sb); + } +} diff --git "a/BOJ/20001-25000353円262円210円/SB_22944.java" "b/BOJ/20001-25000353円262円210円/SB_22944.java" new file mode 100644 index 00000000..a6c3c3e9 --- /dev/null +++ "b/BOJ/20001-25000353円262円210円/SB_22944.java" @@ -0,0 +1,90 @@ +package bfs; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.*; + +public class SB_22944 { + static int N, H, D; + static int K = 0; + static char[][] board; + static Node start; + static int[] dx = {-1, 1, 0, 0}; + static int[] dy = {0, 0, -1, 1}; + + private static int bfs() { + Queue que = new ArrayDeque(); + int[][][] visited = new int[N][N][K + 1]; + for (int[][] box : visited){ + for (int[] row : box){ + Arrays.fill(row, -1); + } + } + que.offer(new Node(start.x, start.y, start.h, start.u, start.cntU)); + visited[start.x][start.y][0] = 0; + + while (!que.isEmpty()) { + Node cur = que.poll(); + if (cur.h==0) continue; // 체력 0이면 죽음 + if (board[cur.x][cur.y]=='E') { // 도착하면 탈출 + return visited[cur.x][cur.y][cur.cntU]; + } + + for (int i = 0; i < 4; i++) { + int nx = cur.x + dx[i]; + int ny = cur.y + dy[i]; + if (!isValid(nx, ny) || visited[nx][ny][cur.cntU]!=-1) continue; + if (board[nx][ny] == 'U') { + if (cur.cntU + 1 <= K && visited[nx][ny][cur.cntU + 1] == -1) { // 우산 안넘치게 조건걸기 + que.add(new Node(nx, ny, cur.h, D, cur.cntU + 1)); + visited[nx][ny][cur.cntU+1] = visited[cur.x][cur.y][cur.cntU] + 1; + } + } + else { + if (cur.u> 0) que.add(new Node(nx, ny, cur.h, cur.u - 1, cur.cntU)); + else que.add(new Node(nx, ny, cur.h-1, cur.u, cur.cntU)); + visited[nx][ny][cur.cntU] = visited[cur.x][cur.y][cur.cntU] + 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)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + N = Integer.parseInt(st.nextToken()); + H = Integer.parseInt(st.nextToken()); + D = Integer.parseInt(st.nextToken()); + + board = new char[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]=='S') start = new Node(i, j, H, 0, 0); + if (board[i][j]=='U') K++; + } + } + + System.out.println(bfs()); + } + + static class Node{ + int x, y, h, u; + int cntU; // 우산 주운 개수 + + public Node(int x, int y, int h, int u, int cntU) { + this.x = x; + this.y = y; + this.h = h; + this.u = u; + this.cntU = cntU; + } + } +} diff --git "a/CodeTree/2021-2022353円205円204円/SB_354円203円211円352円271円224円355円217円255円355円203円204円.java" "b/CodeTree/2021-2022353円205円204円/SB_354円203円211円352円271円224円355円217円255円355円203円204円.java" new file mode 100644 index 00000000..8234566c --- /dev/null +++ "b/CodeTree/2021-2022353円205円204円/SB_354円203円211円352円271円224円355円217円255円355円203円204円.java" @@ -0,0 +1,246 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.*; + +/* +* bfs로 폭탄 묶음 찾기 +* - 이때 가장 큰 폭탄 묶음 있으면 갱신 (빨강 갯수따로, 리스트 저장 따로) +* - 빨강 개수, 기준점 폭탄 정보 필요 (빨강제외 정렬) +* 선택된 폭탄 터트리기 (폭탄 점수++) +* 위에있던 폭탄 아래로 내려오기 (돌 빼고) +* 반시계 90도 회전 진행 +* 또 내려오기 +* */ +public class SB_색깔폭탄 { + static int N, M; + static int[][] board; + + // 큰 폭탄 그룹 체크를 위한 변수 + static int bBRed = Integer.MAX_VALUE; + static Boom bBoom = null; + static List bBooms = new ArrayList(); + static int score = 0; + static int[] dx = {-1, 1, 0, 0}; + static int[] dy = {0, 0, -1, 1}; + + private static void rotate90R() { // 시계방향 90도 회전 + int[][] tmpBoard = new int[N][N]; + for (int i = 0; i < N; i++) { + System.arraycopy(board[i], 0, tmpBoard[i], 0, N); + } + + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + board[i][j] = tmpBoard[N - 1 - j][i]; + } + } + } + + private static void rotate90L() { // 반시계 90도 회전 + int[][] tmpBoard = new int[N][N]; + for (int i = 0; i < N; i++) { + System.arraycopy(board[i], 0, tmpBoard[i], 0, N); + } + + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + board[i][j] = tmpBoard[j][N - 1 - i]; + } + } + } + + private static void tilt() { // 오른쪽으로 밀기 + for (int i = 0; i < N; i++) { + int[] tmp = new int[N]; + Arrays.fill(tmp, -2); + int idx = N-1; + for (int j = N - 1; j>= 0; j--) { + if (board[i][j]==-2) continue; // 빈 곳은 패쓰 + if (board[i][j]==-1) { // 돌만나면 + idx = j; + tmp[idx] = board[i][j]; + idx--; + continue; + } + tmp[idx] = board[i][j]; // 폭탄 떨어지고 + board[i][j] = -2; // 기존 폭탄 위치 빈칸 처리 + idx--; // 폭탄이 떨어질 위치 갱신 + } + System.arraycopy(tmp, 0, board[i], 0, N); + } + } + private static void fallDownBoom() { + // 중력상태 2번 겪음 + // 먼저 반시계 90도 돌리고 오른쪽으로 밀기 (== 첫번째 중력작용후 회전 상태) + rotate90L(); + tilt(); + + // 또 90도 반시계후 오른쪽밀고 시계 90도로 원상복구하면 최종 중력상태 완성 + rotate90L(); + tilt(); + rotate90R(); + } + + private static void removeBoom() { + int size = bBooms.size(); // 점수 업데이트 + score += size * size; + +// System.out.println(bBooms); +// System.out.println(bBoom); + + for (Boom b : bBooms) { // 폭탄 터트리기(-2) + board[b.x][b.y] = -2; + } + + bBRed = Integer.MAX_VALUE; // 큰 폭탄 정보 초기화 + bBoom = null; + bBooms.clear(); + } + + private static void checkBigBoom(List tmp, int RedSize) { + Collections.sort(tmp); // 기준폭탄을 위해 폭탄정렬 + Boom tB = null; + for (Boom b : tmp) { + if (b.c==0) continue; // 빨강폭탄이면 패쓰 + tB = b; // 기준 폭탄 설정 + break; + } + + if (tmp.size()> bBooms.size()) { // 새로운 폭탄 수가 더 크면 갱신 + bBRed = RedSize; + bBoom = tB; + bBooms = new ArrayList(tmp); + return; + } + if (RedSize < bBRed) { // 빨강 폭탄 수가 더 적으면 갱신 + bBRed = RedSize; + bBoom = tB; + bBooms = new ArrayList(tmp); + return; + } + + if (tB.x> bBoom.x) { + bBRed = RedSize; + bBoom = tB; + bBooms = new ArrayList(tmp); + return; + } + + if (tB.y < bBoom.y) { + bBRed = RedSize; + bBoom = tB; + bBooms = new ArrayList(tmp); + } + } + + private static boolean bfs(Boom start, boolean[][] visited) { + Queue que = new ArrayDeque(); + List tmp = new ArrayList(); + Set red = new HashSet(); + que.offer(start); + visited[start.x][start.y] = true; + + if (start.c==0) red.add(start.x * N + start.y); // 시작점도 리스트에 넣기 + tmp.add(start); + + while (!que.isEmpty()) { + Boom cur = que.poll(); + for (int i = 0; i < 4; i++) { + int nx = cur.x + dx[i]; + int ny = cur.y + dy[i]; + if (!isValid(nx, ny) || board[nx][ny] < 0) continue; + if (!visited[nx][ny] && board[nx][ny] == start.c) { // 같은 색 넣기 + que.offer(new Boom(nx, ny, board[nx][ny])); + visited[nx][ny] = true; + tmp.add(new Boom(nx, ny, board[nx][ny])); + } + if (board[nx][ny] == 0 && !red.contains(nx*N+ny)) { // 빨간 색 넣기 + que.offer(new Boom(nx, ny, board[nx][ny])); + visited[nx][ny] = true; + tmp.add(new Boom(nx, ny, board[nx][ny])); + red.add(nx * N + ny); + } + } + } + + if (tmp.size() <= 1 || red.size()==tmp.size()) { // 크기가 2가 안되거나 빨강으로만 이루어져있으면 만들 수 없음 + return false; + } + + // 가장 큰 폭탄 그룹 갱신 + if (tmp.size()>= bBooms.size()) checkBigBoom(tmp, red.size()); + return true; + } + + private static boolean findBigBoom() { + boolean[][] visited = new boolean[N][N]; + + boolean isBoom = false; + for (int i=0; i 0) { + isBoom |= bfs(new Boom(i, j, board[i][j]), visited); + } + } + } + return isBoom; + } + + 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()); + + 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()); + } + } + + while (findBigBoom()) { // 1. 큰 폭탄 묶음 있을때까지 반복 + System.out.println("폭탄 제거 전 보드: " + Arrays.deepToString(board)); + // 2. 폭탄 제거하기 + removeBoom(); + System.out.println("폭탄 제거 후 보드: " + Arrays.deepToString(board)); + + // 3. 폭탄 떨어지기 + fallDownBoom(); + System.out.println("폭탄 중력 후 보드: " + Arrays.deepToString(board)); + } + System.out.println(score); + } + + static class Boom implements Comparable{ + int x, y, c; + + public Boom(int x, int y, int c) { + this.x = x; + this.y = y; + this.c = c; + } + + @Override + public int compareTo(Boom o) { + if (o.x!=this.x) return o.x - this.x; + return this.y - o.y; + } + + @Override + public String toString() { + return "Boom{" + + "x=" + x + + ", y=" + y + + ", c=" + c + + '}'; + } + } +} diff --git "a/Programmers/Level2/lv2_354円266円251円353円217円214円354円234円204円355円227円230円354円260円276円352円270円260円.java" "b/Programmers/Level2/lv2_354円266円251円353円217円214円354円234円204円355円227円230円354円260円276円352円270円260円.java" new file mode 100644 index 00000000..f7fe6b67 --- /dev/null +++ "b/Programmers/Level2/lv2_354円266円251円353円217円214円354円234円204円355円227円230円354円260円276円352円270円260円.java" @@ -0,0 +1,98 @@ +import java.util.*; + +/* +* points: i번위치에 대한 '좌표' 정보 +* routes: 가야할 points의 '인덱스' 정보 +* */ +public class lv2_충돌위험찾기 { + static Map map = new HashMap(); + static List> paths = new ArrayList(); + + private static void move(int sx, int sy, int ex, int ey, List tmp) { + int cx = sx; + int cy = sy; + + while (!(cx == ex && cy == ey)) { // 목표 좌표를 향해 행우선으로 이동 + if (cx> ex) { + cx--; + tmp.add(new Node(cx, cy)); + continue; + } + if (cx < ex) { + cx++; + tmp.add(new Node(cx, cy)); + continue; + } + if (cy> ey) { + cy--; + tmp.add(new Node(cx, cy)); + continue; + } + cy++; + tmp.add(new Node(cx, cy)); + } + } + public static int solution(int[][] points, int[][] routes) { + int ans = 0; + for (int i = 0; i < points.length; i++) { // 포인트 지점을 맵으로 표현 + map.put(i + 1, new Node(points[i][0], points[i][1])); + } + + for (int[] r : routes) { // 로봇별로 경로에따라 이동하기 + int start = r[0]; + int sx = map.get(start).x; + int sy = map.get(start).y; + + List tmp = new ArrayList(); + tmp.add(new Node(sx, sy)); + + for (int i = 1; i < r.length; i++) { + int end = r[i]; + int ex = map.get(end).x; + int ey = map.get(end).y; + + move(sx, sy, ex, ey, tmp); // 목표지점을 향해 이동 + sx = ex; + sy = ey; + } + paths.add(tmp); + } + + int mx = 0; + for (List p : paths) { // 가장 긴 경로 찾기 + int len = p.size(); + mx = Math.max(mx, len); + } + + for (int i = 0; i < mx; i++) { + Set set = new HashSet(); + Set check = new HashSet(); + for (List p : paths) { + if (p.size() <= i) continue; // 이미 끝났으면 패쓰 + + int key = p.get(i).x * 100 + p.get(i).y; + if (check.contains(key)) continue; + if (set.contains(key)) { + check.add(key); + continue; + } + set.add(key); + } + ans += check.size(); // 현재 시간에 충돌 개수 더하기 + } + return ans; + } + public static void main(String[] args) { + int[][] points = {{3, 2}, {6, 4}, {4, 7}, {1, 4}}; + int[][] routes = {{4, 2}, {1, 3}, {2, 4}}; + System.out.println(solution(points, routes)); + } + + static class Node{ + int x, y; + public Node(int x, int y) { + this.x = x; + this.y = y; + } + } +} diff --git a/Programmers/Level3/SB_118669.java b/Programmers/Level3/SB_118669.java new file mode 100644 index 00000000..7785025a --- /dev/null +++ b/Programmers/Level3/SB_118669.java @@ -0,0 +1,86 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.PriorityQueue; + +public class SB_118669 { + static int[] info; + static int[] intensity; + static ArrayList> adj = new ArrayList(); + private static void dijkstra() { + PriorityQueue pq = new PriorityQueue(); + for (int i = 0; i < info.length; i++) { + if (info[i] == 1) { // 입구일때 + pq.offer(new Node(i, 0)); // 우선순위큐에 넣고 + intensity[i] = 0; // 쉬는구간 0 초기화 + } + } + + while (!pq.isEmpty()) { + Node cur = pq.poll(); + if (intensity[cur.u] < cur.cost) continue; // 이미 더 작은 값으로 방문했으면 패쓰 + for (Node nxt : adj.get(cur.u)) { + if (intensity[nxt.u]> Math.max(intensity[cur.u], nxt.cost)) { // 이동과정 중 최대값이 intensity값이 됨 + intensity[nxt.u] = Math.max(intensity[cur.u], nxt.cost); + pq.offer(nxt); + } + } + } + + } + public static int[] solution(int n, int[][] paths, int[] gates, int[] summits) { + // 지점 정보 세팅 + info = new int[n + 1]; + intensity = new int[n + 1]; + for (int g : gates) { + info[g] = 1; // 출입구 1 + } + for (int s : summits) { + info[s] = 2; // 산봉우리 2 + } + Arrays.fill(intensity, Integer.MAX_VALUE); + + // adj만들기 (입구는 나가는 방향, 봉우리는 들어오는 방향, 쉼터는 양방향) + for (int i = 0; i < n + 1; i++) { + adj.add(new ArrayList()); + } + for (int[] path : paths) { + int u = path[0]; + int v = path[1]; + int c = path[2]; + if (info[u] == 1 || info[v] == 2) adj.get(u).add(new Node(v, c)); // 시작이 산봉우리거나 끝이 입구면 각자 들어오고 나가는거 저장안해도 됨 + else if (info[v] == 1 || info[u] == 2) adj.get(v).add(new Node(u, c)); // 시작이 입구거나 끝이 산봉우리면 각자 나가거나 들어오는거 저장안해도 됨 + else { // 쉼터는 양방향으로 저장 + adj.get(u).add(new Node(v, c)); + adj.get(v).add(new Node(u, c)); + } + } + + dijkstra(); + + Arrays.sort(summits); + + int mnP = 0; + int mnC = Integer.MAX_VALUE; + for (int s : summits) { // 구한 쉬는 구간 중 가작 짧은 값 구하기 + if (intensity[s] < mnC) { + mnC = Math.min(mnC, intensity[s]); + mnP = s; + } + } + return new int[]{mnP, mnC}; + } + + static class Node implements Comparable{ + int u, cost; + + public Node(int u, int cost) { + this.u = u; + this.cost = cost; + } + + @Override + public int compareTo(Node o) { + return this.cost-o.cost; + } + } +} diff --git "a/SQL/14354円243円274円354円260円250円/SB_Investments in 2016.sql" "b/SQL/14354円243円274円354円260円250円/SB_Investments in 2016.sql" new file mode 100644 index 00000000..09cf86e8 --- /dev/null +++ "b/SQL/14354円243円274円354円260円250円/SB_Investments in 2016.sql" @@ -0,0 +1,21 @@ +# Write your MySQL query statement below +-- 모든 보험 계약자를 위해 2016 tiv_2016 모든 총 투자 가치의 합계를 보고하는 솔루션을 작성 +-- 조건 1: 하나 이상의 다른 보험 가입자와 동일한 tiv_2015 값을 갖기 +-- 조건 2: 다른 보험 가입자와 같은 도시에 위치하지 않음 +-- 반올림 tiv_2016 소수점 이하 두 자리까지. + +SELECT ROUND(SUM(tiv_2016),2) AS tiv_2016 +FROM Insurance +WHERE tiv_2015 IN ( + SELECT tiv_2015 + FROM Insurance + GROUP BY tiv_2015 + HAVING COUNT(tiv_2015)> 1 +) +AND +(lat, lon) IN ( + SELECT lat, lon + FROM Insurance + GROUP BY lat, lon + HAVING COUNT(*) = 1 +); \ No newline at end of file diff --git "a/SQL/14354円243円274円354円260円250円/SB_Product Price at a Given Date.sql" "b/SQL/14354円243円274円354円260円250円/SB_Product Price at a Given Date.sql" new file mode 100644 index 00000000..baebca0a --- /dev/null +++ "b/SQL/14354円243円274円354円260円250円/SB_Product Price at a Given Date.sql" @@ -0,0 +1,17 @@ +-- 상품 번호, 가격, 가격이 변경된 날짜가 저장된 PRODUCTS 테이블이 있을 때, 2019년 08월 16일까지 상품 가격이 변경된 상품이 있다면 해당 상품 정보(상품 id, 가격) 출력하기 +-- 만약 2019년 08월 16일 이전까지 상품 가격에 대한 정보가 없다면 10 출력 + +WITH PRE AS ( + SELECT product_id, new_price, change_date + FROM Products + WHERE (product_id ,change_date) IN ( + SELECT product_id, MAX(change_date) + FROM Products + WHERE change_date <= "2019-08-16" + GROUP BY product_id + ) +) +SELECT DISTINCT(a.product_id), IFNULL(b.new_price, 10) AS price +FROM Products a +LEFT JOIN PRE b ON a.product_id = b.product_id +-- GROUP BY product_id \ No newline at end of file

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