Skip to content
29 changes: 29 additions & 0 deletions BOJ/1000-5000번/JW_1535.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
public class Main {

public static void main(String[] args) throws Exception {
int n = read();
int[] cost = new int[n];
for (int i = 0; i < n; i++)
cost[i] = read();
int[] get = new int[n];
for (int i = 0; i < n; i++)
get[i] = read();
int[] dp = new int[100];
// 중복 선택이 불가능한 0-1 Knapsack
for (int i = 0; i < n; i++) {
for (int j = 99; j >= cost[i]; j--) {
dp[j] = Math.max(dp[j], dp[j - cost[i]] + get[i]);
}
}
System.out.println(dp[99]);
}

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;
}
}
31 changes: 31 additions & 0 deletions BOJ/1000-5000번/JW_2073.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
public class Main {

public static void main(String[] args) throws Exception {
int d = read(), p = read();
int[] length = new int[p];
int[] width = new int[p];
for (int i = 0; i < p; i++) {
length[i] = read();
width[i] = read();
}
int[] dp = new int[d + 1];
dp[0] = Integer.MAX_VALUE; // 최솟값을 찾기 위해 첫 시작은 최대로 초기화
// 중복 선택이 불가능한 0-1 Knapsack
for (int i = 0; i < p; i++) {
for (int j = d; j >= length[i]; j--) {
// j길이를 만들었을 때 가질 수 있는 파이프의 최대 넓이
dp[j] = Math.max(dp[j], Math.min(dp[j - length[i]], width[i]));
}
}
System.out.println(dp[d]);
}

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;
}
}
65 changes: 65 additions & 0 deletions BOJ/20001-25000번/JW_21939.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class BOJ410 {

static class Problem {
int num, level;

Problem(int num, int level) {
this.num = num;
this.level = level;
}
}

public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
// 문제 레벨과 번호로 정렬해서 저장할 트리 맵
TreeSet<Problem> ts = new TreeSet<>((o1, o2) -> o1.level != o2.level ? o1.level - o2.level : o1.num - o2.num);
// 현재 트리 맵에 어떤 정보가 저장되어 있는지 알려줄 해시 맵
HashMap<Integer, Integer> hm = new HashMap<>();
StringTokenizer st;
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
int p = Integer.parseInt(st.nextToken());
int l = Integer.parseInt(st.nextToken());
Problem problem = new Problem(p, l);
ts.add(problem);
hm.put(p, l);
}
StringBuilder sb = new StringBuilder();
int m = Integer.parseInt(br.readLine());
while (m-- > 0) {
st = new StringTokenizer(br.readLine());
String oper = st.nextToken();
int p = Integer.parseInt(st.nextToken());
int l;
// 명령어 처리
switch (oper) {
case "recommend":
if (p == 1)
sb.append(ts.last().num); // 가장 끝에 있는 문제
else
sb.append(ts.first().num); // 처음에 있는 문제
sb.append("\n");
break;
case "add":
l = Integer.parseInt(st.nextToken()); // 문제 난이도
ts.add(new Problem(p, l)); // 현재 가지고 있는 문제 트리 맵에 입력
hm.put(p, l); // 가지고 있는 문제를 조회하기 위한 해시 맵에 입력
break;
case "solved":
l = hm.get(p); // 해당 문제의 난이도를 가져옴
Problem problem = new Problem(p, l);
ts.remove(problem); // 만들어진 오브젝트와 동일한 객체가 있다면 제거
hm.remove(p); // 맵에서도 제거
break;
}
}
System.out.println(sb);
}
}
60 changes: 60 additions & 0 deletions BOJ/5001-10000번/JW_5021.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;

public class Main {

static HashMap<String, String[]> tree = new HashMap<>(); // 가계도
static HashMap<String, Double> bloodMap = new HashMap<>(); // 혈통

public static void main(String[] args) throws Exception {
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());
// 트리 구조 생성
String root = br.readLine();
bloodMap.put(root, 1D);
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
String child = st.nextToken();
String parent1 = st.nextToken();
String parent2 = st.nextToken();
tree.put(child, new String[] { parent1, parent2 });
bloodMap.put(child, 0D);
bloodMap.putIfAbsent(parent1, 0D);
bloodMap.putIfAbsent(parent2, 0D);
}
String answer = "";
double maxBlood = 0;
while (m-- > 0) {
String name = br.readLine();
double blood = recursive(name); // 재귀로 타겟의 혈통의 값을 찾아주기
if (blood > maxBlood) {
answer = name;
maxBlood = blood;
}
}
System.out.println(answer);
}

// 트리에서의 DP
private static double recursive(String person) {
// 미리 계산된 값이 있다면 반환 -> 메모이제이션
if (bloodMap.containsKey(person) && bloodMap.get(person) > 0) {
return bloodMap.get(person);
}
// 외부인일 경우 0을 반환
if (!tree.containsKey(person)) {
return 0;
}
String[] parents = tree.get(person);
double parent1Blood = recursive(parents[0]) / 2.0; // 부모의 혈통 정보의 절반
double parent2Blood = recursive(parents[1]) / 2.0; // 부모의 혈통 정보의 절반

double personBlood = parent1Blood + parent2Blood; // 둘의 혈통을 합친 것이 타겟의 혈통
bloodMap.replace(person, personBlood); // 메모이제이션
return personBlood;
}
}
105 changes: 105 additions & 0 deletions CodeTree/2019-2020년/JW_시공의_돌풍.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

static int n, m, t, p; // 세로, 가로, 시간, 시공의 돌풍의 위치
// 윗 부분 회전에 맞추기 위해
// 우 -> 상 -> 좌 -> 하
// 순으로 변화량을 저장
static int[] dy = { 0, -1, 0, 1 };
static int[] dx = { 1, 0, -1, 0 };
static int[][] board;

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());
t = 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());
// 마지막 시공의 돌풍의 y좌표
if (board[i][0] == -1)
p = i;
}
// 시간만큼 시뮬레이션
while (t-- > 0) {
spread(); // 확산
rotate(p - 1, 1); // 윗 부분 회전
rotate(p , -1); // 아랫 부분 회전
}
System.out.println(calculate()); // 방 안의 먼지의 총합 계산
}

private static void spread() {
int[][] tempBoard = new int[n][m]; // 확산되는 양을 저장할 새로운 배열
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (board[i][j] > 0) {
int amount = board[i][j] / 5; // 확산될 양
for (int k = 0; k < 4; k++) {
int y = i + dy[k];
int x = j + dx[k];
// 유효한 좌표라면 확산
if (isValid(y, x) && board[y][x] != -1) {
tempBoard[i][j] -= amount; // 확산시킨 곳의 양은 감소
tempBoard[y][x] += amount; // 확산된 곳의 양은 증가
}
}
}
// 원래 방에서 확산으로 인한 변화량을 더해줌
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
board[i][j] += tempBoard[i][j];
}

/*
* @param s: 시공의 돌풍의 y좌표
* @param mode: 윗 회전인지 아랫 회전인지 알려주는 변수
*
* mode에 따라서 회전하는 방향이 결정됨
*/
private static void rotate(int s, int mode) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

시계 방향, 반시계 방향 부분 mode로 나누고, dir = (dir + mode + 4) % 4로 방향 재설정을 해주니 아주 깔끔하네요!!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니다 ㅎ
어떻게 하면 한번에 처리할까 고민을 하다가 생각해낸 방법인데
지영님처럼 아예 어떻게 움직일지 배열을 전달하는 방법도 괜찮은 것 같아요!

int prev = 0; // 이전 값
int dir = 0;
int y = s, x = 1;
// 시공의 돌풍으로 돌아올 때까지 반복
while (!(y == s && x == 0)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다들 돌풍의 회전 멋있게 구현하셨네요..! while문 조건을 시공의 돌풍으로 돌아올때까지 건 부분 좋네요!!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

회전 부분 구현하는게 복잡했는데 실제 현장에서는 깡 구현이 더 빠를 것 같아요

int temp = board[y][x]; // 원래 값 기억
board[y][x] = prev; // 다음 좌표를 이전 값으로 갱신
prev = temp; // 이전 값을 원래 값으로 갱신
int ny = y + dy[dir];
int nx = x + dx[dir];
// 다음 좌표가 경계를 벗어난다면
if (!isValid(ny, nx)) {
// 방향 재설정
dir = (dir + mode + 4) % 4;
ny = y + dy[dir];
nx = x + dx[dir];
}
// 다음 좌표 결정
y = ny;
x = nx;
}
}

// 방 안의 먼지의 총합을 계산
private static int calculate() {
// 시공의 돌풍이 -1이므로 전처리
int sum = 2;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
sum += board[i][j];
return sum;
}

// 경계 체크
private static boolean isValid(int y, int x) {
return 0 <= y && y < n && 0 <= x && x < m;
}
}
11 changes: 11 additions & 0 deletions Programmers/Level2/JW_49993.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Solution {
public int solution(String skill, String[] skill_trees) {
int answer = 0;
String regex = "[^" + skill + "]"; // 스킬 순서 외의 문자를 지우기 위한 정규표현식
for (String skill_tree : skill_trees)
// 문자를 지웠을 때, 남은 문자가 스킬 순서와 일치할 때
if (skill.indexOf(skill_tree.replaceAll(regex, "")) == 0)
answer++;
return answer;
}
}
20 changes: 20 additions & 0 deletions Programmers/Level3/JW_12938.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class Solution {
public int[] solution(int n, int s) {
int[] answer = new int[n];
// 1로만 이루어진 집합으로도 만들 수 없을 경우 -1 리턴
if (n > s)
return new int[] { -1 };
// 오름차순으로 정렬하기 위해 뒤에서 부터 값 설정
for (int i = n - 1; i >= 0; i--) {
// 마지막 위치에 만들 수 있는 최댓값 설정
answer[i] = s / n;
// 나머지가 존재한다면 +1
if (s % n != 0)
answer[i]++;
// n과 s값 변경
n--;
s -= answer[i];
}
return answer;
}
}
11 changes: 11 additions & 0 deletions SQL/07주차/JW_Biggest_Single_Number.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
SELECT
MAX(num) num
FROM
(SELECT
num
FROM
MyNumbers
GROUP BY
num
HAVING
COUNT(num) = 1) temp
16 changes: 16 additions & 0 deletions SQL/07주차/JW_Product_Sales_Analysis_III.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
SELECT
product_id
, year `first_year`
, quantity
, price
FROM
Sales
WHERE (product_id, year) in (
SELECT
product_id
, MIN(year) min_Year
FROM
Sales
GROUP BY
product_id
)