Skip to content

Commit a584174

Browse files
authored
Merge pull request #311 from GreatAlgorithm-Study/dahye
[23주차] 고다혜
2 parents aa3aa0c + 856086b commit a584174

9 files changed

+657
-0
lines changed

BOJ/1000-5000번/DH_1135.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import java.io.*;
2+
import java.util.*;
3+
4+
/*
5+
* 뉴스 전하기
6+
*/
7+
8+
public class DH_1135 {
9+
public static void main(String[] args) throws Exception {
10+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
11+
int N = Integer.parseInt(br.readLine());
12+
13+
int[] reverse = new int[N]; // 부모를 저장하는 배열
14+
15+
StringTokenizer st = new StringTokenizer(br.readLine());
16+
17+
for(int i = 0; i < N; i++) {
18+
int p = Integer.parseInt(st.nextToken());
19+
20+
if(p == -1) continue;
21+
reverse[i] = p; // 자신의 부모 저장
22+
}
23+
24+
ArrayList<int[]> time[] = new ArrayList[N]; // 인접리스트 (노드, 걸리는 시간) 저장
25+
for(int i = 0; i < time.length; i++) time[i] = new ArrayList<>();
26+
27+
int result = 0;
28+
29+
for(int i = N - 1; i >= 0; i--) {
30+
// 현재 노드에 인접해있는 노드를 걸리는 시간 내림차순으로 정렬함
31+
Collections.sort(time[i], (o1, o2) -> Integer.compare(o2[1], o1[1]));
32+
33+
int tmp = 0; // 현재 노드까지 걸리는 시간
34+
35+
int childCnt = 1; // 자식의 수
36+
37+
// 제일 오래 걸리는 시간 더해주기
38+
for(int[] child: time[i]) {
39+
tmp = Math.max(tmp, childCnt + child[1]);
40+
childCnt += 1;
41+
}
42+
43+
// 인접리스트 만들어나가기
44+
time[reverse[i]].add(new int[] {i, tmp});
45+
result = Math.max(result, tmp);
46+
}
47+
48+
System.out.println(result);
49+
}
50+
}

BOJ/1000-5000번/DH_1450.java

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import java.io.*;
2+
import java.util.*;
3+
4+
/*
5+
* 냅색 문제
6+
*/
7+
8+
public class DH_1450 {
9+
static int N;
10+
static long C;
11+
static int[] arr1, arr2;
12+
13+
public static void main(String[] args) throws Exception {
14+
initInput();
15+
solution();
16+
}
17+
18+
static void solution() {
19+
20+
// 반씩 나눈 물건들의 각각의 그룹에서 더했을 때 나올 수 있는 모든 경우 구해주기
21+
ArrayList<Long> list1 = new ArrayList<>();
22+
ArrayList<Long> list2 = new ArrayList<>();
23+
24+
getSumList(list1, arr1, 0, 0);
25+
getSumList(list2, arr2, 0, 0);
26+
27+
// 이분탐색을 위한 정렬
28+
Collections.sort(list1);
29+
Collections.sort(list2);
30+
31+
// N개의 물건에 가방을 넣는 방법의 수 구하기
32+
System.out.println(getCount(list1, list2));
33+
}
34+
35+
static long getCount(ArrayList<Long> list1, ArrayList<Long> list2) {
36+
long cnt = 0;
37+
38+
for(long n: list1) {
39+
int s = 0, e = list2.size() - 1;
40+
41+
long leftValue = C - n;
42+
43+
while(s <= e) {
44+
int m = (s + e) / 2;
45+
46+
// upperbound 구해야 됨 (s 옮기기)
47+
if(list2.get(m) <= leftValue) s = m + 1;
48+
else e = m - 1;
49+
}
50+
51+
// 인덱스를 개수로 바꿔주기 위해 + 1을 함
52+
cnt += e + 1;
53+
}
54+
55+
return cnt;
56+
}
57+
static void getSumList(ArrayList<Long> list, int[] arr, int depth, long sum) {
58+
if(depth == arr.length) {
59+
list.add(sum);
60+
return;
61+
}
62+
63+
getSumList(list, arr, depth + 1, sum + arr[depth]);
64+
getSumList(list, arr, depth + 1, sum);
65+
}
66+
static void initInput() throws Exception {
67+
68+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
69+
StringTokenizer st = new StringTokenizer(br.readLine());
70+
71+
N = Integer.parseInt(st.nextToken()); // 물건의 개수
72+
C = Integer.parseInt(st.nextToken()); // 최대 담을 수 있는 무게
73+
74+
// 입력되는 물건들 반 씩 나누어서 생각하기
75+
arr2 = new int[N / 2];
76+
77+
if(N % 2 == 0) arr1 = new int[N / 2];
78+
else arr1 = new int[N / 2 + 1];
79+
80+
st = new StringTokenizer(br.readLine());
81+
82+
for(int i = 0; i < arr1.length; i++) arr1[i] = Integer.parseInt(st.nextToken());
83+
for(int i = 0; i < arr2.length; i++) arr2[i] = Integer.parseInt(st.nextToken());
84+
}
85+
}

BOJ/15001-20000번/DH_19237.java

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
import java.io.*;
2+
import java.util.*;
3+
4+
/*
5+
* 어른 상어
6+
* 시간 범위 설정 잘 하기!!
7+
*/
8+
9+
public class DH_19237 {
10+
static class Node {
11+
int sharkIdx, time;
12+
13+
public Node() {}
14+
public Node(int sharkIdx, int time) {
15+
this.sharkIdx = sharkIdx;
16+
this.time = time;
17+
}
18+
19+
public void update(int sharkIdx, int time) {
20+
this.sharkIdx = sharkIdx;
21+
this.time = time;
22+
}
23+
}
24+
static class Shark {
25+
boolean isDie;
26+
int pos, dir;
27+
int[][] priority;
28+
29+
public Shark() {}
30+
31+
public Shark(int pos, int dir) {
32+
this.pos = pos;
33+
this.dir = dir;
34+
}
35+
36+
public void setPos(int pos) {
37+
this.pos = pos;
38+
}
39+
40+
public void setDir(int dir) {
41+
this.dir = dir;
42+
}
43+
44+
public void setPriority(int[][] priority) {
45+
this.priority = priority;
46+
}
47+
}
48+
static int N, M, k, liveSharkCnt; // liveSharkCnt: 살아있는 상어 수
49+
static int[][] idx; // 상어가 있는 위치를 idx로 저장
50+
static Node[][] smell; // 냄새에 대한 정보 (상어 idx, 냄새 유지 시간)
51+
static Shark[] sharks; // 상어들에 대한 정보
52+
static int[] dr = {-1, 1, 0, 0}, dc = {0, 0, -1, 1}; // 상, 하, 좌, 우
53+
public static void main(String[] args) throws Exception {
54+
initInput();
55+
solution();
56+
}
57+
58+
static void solution() {
59+
int time = 0;
60+
boolean flag = false;
61+
62+
// while(time < 1_001)으로 하면 1001초까지 보게 됨 !! =ㅅ=,,,
63+
while(time < 1_000) {
64+
65+
moveSharks();
66+
67+
decreaseSmell(); // 기존에 있던 냄새 1씩 줄이기
68+
updateSmell(); // 상어들이 움직인 자리에 상어 냄새 표시해주기
69+
70+
time++;
71+
72+
if(liveSharkCnt == 1) {
73+
flag = true;
74+
break;
75+
}
76+
}
77+
78+
System.out.println(flag ? time : -1);
79+
}
80+
81+
// 상어가 새로 그 자리에 갔을 때, 해당 좌표에서 냄새 업데이트해주기
82+
static void updateSmell() {
83+
for(int idx = 1; idx < sharks.length; idx++) {
84+
if(sharks[idx].isDie) continue;
85+
86+
int pos = sharks[idx].pos;
87+
int r = pos / N;
88+
int c = pos % N;
89+
90+
smell[r][c].update(idx, k); // (r, c) 지점에 idx 상어의 냄새가 k초 동안 지속됨
91+
}
92+
}
93+
94+
// 1초가 지날 때 마다 상어 냄새 유지도 줄여주기
95+
static void decreaseSmell() {
96+
for(int r = 0; r < smell.length; r++) {
97+
for(int c = 0; c < smell[0].length; c++) {
98+
if(smell[r][c].time == 0) continue;
99+
100+
smell[r][c].time--;
101+
if(smell[r][c].time == 0) smell[r][c].sharkIdx = 0;
102+
}
103+
}
104+
}
105+
106+
// 상어들 움직여주기
107+
static void moveSharks() {
108+
int[][] nextIdxMap = new int[N][N]; // 이동한 다음 상어들의 인덱스를 저장하는 배열
109+
110+
// idx가 큰 상어부터 이동해주기
111+
for(int idx = sharks.length - 1; idx > 0; idx--) {
112+
if(sharks[idx].isDie) continue; // 겪자 밖으로 쫓겨난 상어는 움직이지 못함
113+
114+
Shark current = sharks[idx];
115+
116+
int moveDir = -1; // 상어가 움직일 방향
117+
int cr = current.pos / N, cc = current.pos % N; // 현재 상어의 위치
118+
119+
int mr = cr, mc = cc; // 이동할 상어의 위치
120+
121+
for(int d = 0; d < 4; d++) {
122+
int dir = current.priority[current.dir][d]; // 상어 방향의 우선순위에 따라 4방으로 확인
123+
124+
int nr = cr + dr[dir];
125+
int nc = cc + dc[dir];
126+
127+
if(!check(nr, nc)) continue; // 범위를 벗어난다면 다른 방향 확인
128+
// 다른 상어의 냄새가 있다면 다른 방향으로 확인
129+
if(smell[nr][nc].sharkIdx != idx && smell[nr][nc].sharkIdx != 0) continue;
130+
131+
// 이동할 위치를 정하지 못했는데, 그 다음 좌표에 자신의 냄새가 난다면 일단 이동할 위치로 정해주기
132+
if(moveDir == -1 && smell[nr][nc].sharkIdx == idx) {
133+
moveDir = dir;
134+
mr = nr;
135+
mc = nc;
136+
}
137+
138+
// 냄새가 없는 칸이 나오면 바로 그 방향으로 이동하기
139+
if(smell[nr][nc].sharkIdx == 0) {
140+
moveDir = dir;
141+
mr = nr;
142+
mc = nc;
143+
break;
144+
}
145+
}
146+
147+
// 상어가 향하고 있는 방향 수정
148+
current.dir = moveDir;
149+
150+
// 혹시라도 상어가 움직이지 못하는 경우가 있을까봐 조건문으로 설정함
151+
// 상어가 이동할 방향이 있다면, 해당 방향으로 상어 움직여주기
152+
if(moveDir != -1) {
153+
int nextPos = mr * N + mc;
154+
current.pos = nextPos;
155+
}
156+
157+
// 이미 이동한 상어가 있는 경우
158+
// => idx가 작은 상어가 오게 되고, 기존에 있는 상어는 격자 밖으로 내쫓기게 됨
159+
if(nextIdxMap[mr][mc] != 0) {
160+
int biggerIdx = nextIdxMap[mr][mc];
161+
162+
sharks[biggerIdx].isDie = true;
163+
liveSharkCnt--;
164+
}
165+
166+
nextIdxMap[mr][mc] = idx;
167+
}
168+
169+
// idx배열 갱신하기
170+
idx = nextIdxMap;
171+
}
172+
173+
static boolean check(int r, int c) {
174+
return r >= 0 && r < N && c >= 0 && c < N;
175+
}
176+
177+
static void initInput() throws Exception {
178+
System.setIn(new FileInputStream("./input/BOJ19237.txt"));
179+
180+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
181+
StringTokenizer st = new StringTokenizer(br.readLine());
182+
183+
N = Integer.parseInt(st.nextToken()); // N × N 크기의 mapN
184+
M = Integer.parseInt(st.nextToken()); // 1 ≤ 상어의 번호 ≤ M
185+
k = Integer.parseInt(st.nextToken()); // 냄새 유지 시간
186+
liveSharkCnt = M; // 총 M개의 상어가 살아있음
187+
188+
idx = new int[N][N];
189+
smell = new Node[N][N];
190+
191+
sharks = new Shark[M + 1];
192+
for(int idx = 1; idx < sharks.length; idx++) sharks[idx] = new Shark();
193+
194+
for(int r = 0; r < idx.length; r++) {
195+
st = new StringTokenizer(br.readLine());
196+
for(int c = 0; c < idx[0].length; c++) {
197+
198+
smell[r][c] = new Node();
199+
200+
int currentIdx = Integer.parseInt(st.nextToken());
201+
idx[r][c] = currentIdx;
202+
203+
if(currentIdx == 0) continue;
204+
smell[r][c] = new Node(idx[r][c], k);
205+
206+
int pos = r * N + c;
207+
sharks[currentIdx].setPos(pos);
208+
}
209+
}
210+
211+
st = new StringTokenizer(br.readLine());
212+
213+
for(int i = 1; i < sharks.length; i++) {
214+
int dir = Integer.parseInt(st.nextToken()) - 1;
215+
sharks[i].setDir(dir);
216+
}
217+
218+
for(int idx = 1; idx < sharks.length; idx++) {
219+
int[][] priorityDir = new int[4][4];
220+
221+
for(int d = 0; d < 4; d++) {
222+
st = new StringTokenizer(br.readLine());
223+
224+
for(int i = 0; i < 4; i++) {
225+
int dir = Integer.parseInt(st.nextToken()) - 1;
226+
priorityDir[d][i] = dir;
227+
}
228+
}
229+
230+
sharks[idx].setPriority(priorityDir);
231+
}
232+
}
233+
}

0 commit comments

Comments
 (0)