Skip to content

Commit 8b8cc87

Browse files
authored
Merge pull request #124 from Jewan1120/main
[9주차] 백제완
2 parents 2495c86 + 21dff27 commit 8b8cc87

File tree

9 files changed

+432
-0
lines changed

9 files changed

+432
-0
lines changed

BOJ/1000-5000번/JW_2098.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import java.util.Arrays;
2+
3+
public class JW_2098 {
4+
static int n;
5+
static int[][] distance; // 각 거리를 정보
6+
static int[][] dp; // 메모이제이션을 위한 DP배열
7+
static int INF = Integer.MAX_VALUE >> 2; // 적절한 최댓값
8+
9+
public static void main(String[] args) throws Exception {
10+
n = read();
11+
distance = new int[n][n];
12+
for (int i = 0; i < n; i++)
13+
for (int j = 0; j < n; j++) {
14+
int d = read();
15+
// 거리 정보가 없는 경우에는 최댓값으로 설정
16+
if (d == 0)
17+
d = INF;
18+
distance[i][j] = d;
19+
}
20+
dp = new int[n][1 << n];
21+
// dp배열 초기화
22+
for (int i = 0; i < n; i++)
23+
Arrays.fill(dp[i], -1);
24+
// 0번 도시에서 출발하는 외판원 순회
25+
int result = tsp(0, 1);
26+
System.out.println(result);
27+
}
28+
29+
// 외판원 순회
30+
// @param city 현재 도시
31+
// @param visited 비트마스킹 방문처리
32+
private static int tsp(int city, int visited) {
33+
// 모든 도시를 방문했다면
34+
if (visited == (1 << n) - 1)
35+
// 원래 도시로 돌아가는 거리를 반환
36+
return distance[city][0];
37+
// 미리 계산된 최솟값이 있다면 반환
38+
if (dp[city][visited] != -1)
39+
return dp[city][visited];
40+
int result = INF; // 해당 도시를 방문했을 때 최솟값을 구하기 위한 변수
41+
for (int nextCity = 0; nextCity < n; nextCity++) {
42+
// 방문한 도시라면 건너뜀
43+
if ((visited & (1 << nextCity)) != 0)
44+
continue;
45+
// 다음 도시를 방문
46+
int temp = distance[city][nextCity] + tsp(nextCity, visited | (1 << nextCity));
47+
// 해당 도시에서 가질 수 있는 최솟값 갱신
48+
result = Math.min(result, temp);
49+
}
50+
// 계산된 값으로 메모이제이션
51+
dp[city][visited] = result;
52+
return result;
53+
}
54+
55+
// 빠른 입력 함수
56+
private static int read() throws Exception {
57+
int c, n = System.in.read() & 15;
58+
while ((c = System.in.read()) >= 48)
59+
n = (n << 3) + (n << 1) + (c & 15);
60+
if (c == 13)
61+
System.in.read();
62+
return n;
63+
}
64+
}

BOJ/1000-5000번/JW_2660.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import java.io.BufferedReader;
2+
import java.io.InputStreamReader;
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.StringTokenizer;
6+
7+
public class JW_2660 {
8+
9+
static final int INF = Integer.MAX_VALUE >> 2;
10+
11+
public static void main(String[] args) throws Exception {
12+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
13+
int n = Integer.parseInt(br.readLine());
14+
// 그래프 선언 및 초기화
15+
int[][] graph = new int[n + 1][n + 1];
16+
for (int i = 0; i < n + 1; i++) {
17+
Arrays.fill(graph[i], INF);
18+
graph[i][i] = 0;
19+
}
20+
while (true) {
21+
StringTokenizer st = new StringTokenizer(br.readLine());
22+
int u = Integer.parseInt(st.nextToken());
23+
int v = Integer.parseInt(st.nextToken());
24+
// 종료 조건
25+
if (u == -1 && v == -1)
26+
break;
27+
// 양방향 그래프
28+
graph[u][v] = 1;
29+
graph[v][u] = 1;
30+
}
31+
// 플로이드 와샬
32+
for (int k = 1; k < n + 1; k++)
33+
for (int i = 1; i < n + 1; i++)
34+
for (int j = 1; j < n + 1; j++)
35+
if (graph[i][j] > graph[i][k] + graph[k][j]) {
36+
graph[i][j] = graph[i][k] + graph[k][j];
37+
}
38+
int min = 50; // 최소 스코어
39+
ArrayList<Integer> al = new ArrayList<>();
40+
for (int i = 1; i < n + 1; i++) {
41+
int score = 0;
42+
// 최단 거리 중 최댓값 찾기
43+
for (int j = 1; j < n + 1; j++)
44+
score = Math.max(score, graph[i][j]);
45+
// 최솟값을 갱신 할 수 있다면
46+
if (min > score) {
47+
min = score; // 최솟값 갱신
48+
al.clear(); // 리스트 비우기
49+
al.add(i); // 리스트에 추가
50+
// 최솟값과 동일하면
51+
} else if (min == score)
52+
al.add(i); // 리스트에 추가
53+
}
54+
StringBuilder sb = new StringBuilder();
55+
sb.append(max).append(" ").append(al.size()).append("\n");
56+
for (int i : al) {
57+
sb.append(i).append(" ");
58+
}
59+
System.out.println(sb);
60+
}
61+
}

BOJ/10001-15000번/JW_13164.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import java.util.Arrays;
2+
3+
public class JW_13164 {
4+
5+
public static void main(String[] args) throws Exception {
6+
int n = read(), k = read();
7+
int[] arr = new int[n];
8+
for (int i = 0; i < n; i++)
9+
arr[i] = read();
10+
// 다음 사람과 같은 조가 되었을 때 비용을 저장할 배열
11+
int[] diff = new int[n - 1];
12+
// 다음 사람과의 키 차이 계산
13+
for (int i = 0; i < n - 1; i++)
14+
diff[i] = arr[i + 1] - arr[i];
15+
// 오름차 순으로 정렬
16+
Arrays.sort(diff);
17+
int answer = 0;
18+
// 키 차이가 별로 안나는 조합은 묶어도 됨
19+
for (int i = 0; i < n - k; i++)
20+
answer += diff[i];
21+
System.out.println(answer);
22+
}
23+
24+
private static int read() throws Exception {
25+
int c, n = System.in.read() & 15;
26+
while ((c = System.in.read()) >= 48)
27+
n = (n << 3) + (n << 1) + (c & 15);
28+
if (c == 13)
29+
System.in.read();
30+
return n;
31+
}
32+
}

BOJ/10001-15000번/JW_14620.java

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
public class JW_24620 {
2+
static int n;
3+
static int[][] board;
4+
static boolean[][] visited;
5+
// 현재 위치 + 상하좌우를 확인하기 위한 변화량
6+
static int[] dy = { 0, 1, -1, 0, 0 };
7+
static int[] dx = { 0, 0, 0, 1, -1 };
8+
static int min = Integer.MAX_VALUE;
9+
10+
public static void main(String[] args) throws Exception {
11+
n = read();
12+
board = new int[n][n];
13+
visited = new boolean[n][n];
14+
for (int i = 0; i < n; i++)
15+
for (int j = 0; j < n; j++)
16+
board[i][j] = read();
17+
// 완전 탐색
18+
recursive(0, 0, 0);
19+
System.out.println(min);
20+
}
21+
22+
private static void recursive(int depth, int total, int p) {
23+
// 3개를 다 심었다면 최솟값 갱신
24+
if (depth == 3) {
25+
min = Math.min(min, total);
26+
return;
27+
}
28+
// 심을 수 있는 위치 찾기
29+
for (int i = p; i < n * n; i++) {
30+
int y = i / n, x = i % n;
31+
boolean isPossible = true;
32+
// 모든 유효성을 통과하는지 확인
33+
for (int j = 0; j < 5; j++) {
34+
int ny = y + dy[j];
35+
int nx = x + dx[j];
36+
if (!isValid(ny, nx)) {
37+
isPossible = false;
38+
}
39+
}
40+
// 심을 수 있는 위치일 경우
41+
if (isPossible) {
42+
int sum = 0;
43+
// 방문 처리
44+
for (int j = 0; j < 5; j++) {
45+
int ny = y + dy[j];
46+
int nx = x + dx[j];
47+
visited[ny][nx] = true;
48+
sum += board[ny][nx];
49+
}
50+
// 다음 깊이의 재귀 진행
51+
recursive(depth + 1, total + sum, i + 1);
52+
53+
// 백 트래킹
54+
for (int j = 0; j < 5; j++) {
55+
int ny = y + dy[j];
56+
int nx = x + dx[j];
57+
visited[ny][nx] = false;
58+
}
59+
}
60+
}
61+
}
62+
63+
// 경계 체크 및 방문하지 않았는지 유효성 검증
64+
private static boolean isValid(int y, int x) {
65+
return 0 <= y && y < n && 0 <= x && x < n && !visited[y][x];
66+
}
67+
68+
// 빠른 입력 함수
69+
private static int read() throws Exception {
70+
int c, n = System.in.read() & 15;
71+
while ((c = System.in.read()) >= 48)
72+
n = (n << 3) + (n << 1) + (c & 15);
73+
if (c == 13)
74+
System.in.read();
75+
return n;
76+
}
77+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import java.io.BufferedReader;
2+
import java.io.InputStreamReader;
3+
import java.util.ArrayDeque;
4+
import java.util.Deque;
5+
import java.util.PriorityQueue;
6+
import java.util.StringTokenizer;
7+
8+
public class JW_전투_로봇 {
9+
10+
static int n;
11+
static int[][] board;
12+
static int[] dy = { -1, 1, 0, 0 };
13+
static int[] dx = { 0, 0, -1, 1 };
14+
static int level = 2, count = 0, totalMove = 0;
15+
16+
public static void main(String[] args) throws Exception {
17+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
18+
n = Integer.parseInt(br.readLine());
19+
board = new int[n][n];
20+
int sy = 0, sx = 0;
21+
for (int i = 0; i < n; i++) {
22+
StringTokenizer st = new StringTokenizer(br.readLine());
23+
for (int j = 0; j < n; j++) {
24+
int p = Integer.parseInt(st.nextToken());
25+
// 초기 로봇 위치 저장
26+
if (p == 9) {
27+
sy = i;
28+
sx = j;
29+
} else if (p != 0) {
30+
board[i][j] = p;
31+
}
32+
}
33+
}
34+
Deque<int[]> dq = new ArrayDeque<>();
35+
boolean[][] visited = new boolean[n][n];
36+
dq.offer(new int[] { 0, sy, sx });
37+
// BFS
38+
while (!dq.isEmpty()) {
39+
// 처리할 수 있는 몬스터들의 위치에 따라 우선 순위 부여
40+
PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o1[0] != o2[0] ? o1[0] - o2[0] : o1[1] - o2[1]);
41+
// 깊이 별로 BFS 진행
42+
int t = dq.size();
43+
while (t-- > 0) {
44+
int[] cur = dq.poll();
45+
int y = cur[1], x = cur[2];
46+
if (visited[y][x])
47+
continue;
48+
visited[y][x] = true;
49+
// 해당 레벨에서 잡을 수 있는 몬스터가 존재한다면 우선 순위 큐에 저장
50+
if (isCatch(y, x)) {
51+
pq.offer(cur);
52+
continue;
53+
}
54+
for (int i = 0; i < 4; i++) {
55+
int ny = y + dy[i], nx = x + dx[i];
56+
if (isValid(ny, nx) && !visited[ny][nx]) {
57+
dq.offer(new int[] { cur[0] + 1, ny, nx });
58+
}
59+
}
60+
}
61+
// 해당 깊이에서 처리할 수 있는 몬스터를 1개 이상 발견했다면
62+
if (!pq.isEmpty()) {
63+
// 우선 순위가 가장 높은 몬스터를 처리
64+
int[] cur = pq.poll();
65+
totalMove += cur[0];
66+
int y = cur[1], x = cur[2];
67+
board[y][x] = 0;
68+
// 없앤 몬스터의 수 갱신과 레벨 업
69+
count++;
70+
if (count == level) {
71+
level++;
72+
count = 0;
73+
}
74+
// 큐를 비우고 해당 위치에서 다시 시작
75+
dq.clear();
76+
dq.offer(new int[] { 0, y, x });
77+
visited = new boolean[n][n];
78+
}
79+
}
80+
System.out.println(totalMove);
81+
}
82+
83+
// 몬스터를 없앨 수 있는지 확인하는 함수
84+
private static boolean isCatch(int y, int x) {
85+
return 0 < board[y][x] && board[y][x] < level;
86+
}
87+
88+
// 경계 체크 함수
89+
private static boolean isValid(int y, int x) {
90+
return 0 <= y && y < n && 0 <= x && x < n && board[y][x] <= level;
91+
}
92+
}

Programmers/Level3/JW_118668.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import java.util.Arrays;
2+
3+
class JW_118668 {
4+
public int solution(int alp, int cop, int[][] problems) {
5+
// 모든 문제를 풀기 위한 최솟값을 찾기 위해 초기화
6+
int maxAlp = alp, maxCop = cop;
7+
for (int i = 0; i < problems.length; i++) {
8+
maxAlp = Math.max(maxAlp, problems[i][0]);
9+
maxCop = Math.max(maxCop, problems[i][1]);
10+
}
11+
// DP 배열 초기화
12+
int[][] dp = new int[maxAlp + 1][maxCop + 1];
13+
for (int i = 0; i < maxAlp + 1; i++)
14+
Arrays.fill(dp[i], Integer.MAX_VALUE >> 2);
15+
dp[alp][cop] = 0;
16+
17+
// DP
18+
// 현재 값 기준으로 다음 값 결정하기
19+
for (int i = alp; i < maxAlp + 1; i++) {
20+
for (int j = cop; j < maxCop + 1; j++) {
21+
// 알고력 증가
22+
if (i < maxAlp)
23+
dp[i + 1][j] = Math.min(dp[i + 1][j], dp[i][j] + 1);
24+
// 코딩력 증가
25+
if (j < maxCop)
26+
dp[i][j + 1] = Math.min(dp[i][j + 1], dp[i][j] + 1);
27+
// 문제 풀기
28+
for (int[] problem : problems)
29+
// 풀 수 있는 문제라면
30+
if (i >= problem[0] && j >= problem[1]) {
31+
// 능력치 증가
32+
int nextAlp = Math.min(maxAlp, i + problem[2]);
33+
int nextCop = Math.min(maxCop, j + problem[3]);
34+
dp[nextAlp][nextCop] = Math.min(dp[nextAlp][nextCop], dp[i][j] + problem[4]);
35+
}
36+
}
37+
}
38+
return dp[maxAlp][maxCop];
39+
}
40+
}

0 commit comments

Comments
 (0)