Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 0d5ac1a

Browse files
authored
Merge pull request #345 from GreatAlgorithm-Study/dahye
[26주차] 고다혜
2 parents 222dd3e + 2e540c3 commit 0d5ac1a

File tree

5 files changed

+640
-0
lines changed

5 files changed

+640
-0
lines changed

‎BOJ/1000-5000번/DH_2521.java

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import java.io.*;
2+
import java.util.*;
3+
4+
/*
5+
* 거울 설치
6+
*/
7+
8+
public class DH_2521 {
9+
static final int INF = Integer.MAX_VALUE;
10+
11+
static class Node implements Comparable<Node> {
12+
int e, mirrorCnt;
13+
14+
public Node(int e, int mirrorCnt) {
15+
this.e = e;
16+
this.mirrorCnt = mirrorCnt;
17+
}
18+
19+
@Override
20+
public int compareTo(Node o) {
21+
return Integer.compare(this.mirrorCnt, o.mirrorCnt);
22+
}
23+
}
24+
static ArrayList<Integer> door;
25+
static ArrayList<Integer>[] adj;
26+
static char[][] map;
27+
static int N;
28+
29+
public static void main(String[] args) throws Exception {
30+
initInput();
31+
setAdj();
32+
System.out.println(dijkstra());
33+
}
34+
35+
static int[] dr = {-1, 1, 0, 0}, dc = {0, 0, -1, 1};
36+
37+
static void initInput() throws Exception {
38+
39+
System.setIn(new FileInputStream("./input/BOJ2521.txt"));
40+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
41+
42+
N = Integer.parseInt(br.readLine());
43+
44+
map = new char[N][N];
45+
46+
adj = new ArrayList[N * N];
47+
for(int i = 0; i < adj.length; i++) adj[i] = new ArrayList<Integer>();
48+
49+
door = new ArrayList<Integer>(); // 문의 위치 저장
50+
51+
for(int r = 0; r < N; r++) {
52+
map[r] = br.readLine().toCharArray();
53+
54+
for(int c = 0; c < N; c++) {
55+
if(map[r][c] != '!' && map[r][c] != '#') continue;
56+
57+
int pos = r * N + c;
58+
if(map[r][c] == '#') door.add(pos);
59+
}
60+
}
61+
}
62+
63+
// 인접리스트 만들기
64+
static void setAdj() {
65+
Queue<int[]> q = new ArrayDeque<int[]>();
66+
67+
for(int r = 0; r < N; r++) {
68+
for(int c = 0; c < N; c++) {
69+
70+
// !이거나 #이면서 직선으로 이동할 때, 다른 !이나 #을 만날 수 있다면 인접리스트 만들어주기
71+
if(map[r][c] != '!' && map[r][c] != '#') continue;
72+
73+
int pos = r * N + c;
74+
75+
// 4방으로 직선으로 이동하기
76+
for(int d = 0; d < 4; d++) {
77+
int nr = r + dr[d];
78+
int nc = c + dc[d];
79+
80+
if(!check(nr, nc) || map[nr][nc] == '*') continue;
81+
q.add(new int[] {nr, nc, d});
82+
}
83+
84+
while(!q.isEmpty()) {
85+
86+
int[] poll = q.poll();
87+
int cr = poll[0], cc = poll[1];
88+
89+
// 이동하다가 !이나 #을 만나면 인접리스트에 정보 저장해주기
90+
if(map[cr][cc] == '!' || map[cr][cc] == '#') {
91+
adj[pos].add(cr * N + cc);
92+
}
93+
94+
int d = poll[2];
95+
int nr = poll[0] + dr[d];
96+
int nc = poll[1] + dc[d];
97+
98+
if(!check(nr, nc) || map[nr][nc] == '*') continue;
99+
100+
q.add(new int[] {nr, nc, d});
101+
}
102+
}
103+
}
104+
}
105+
106+
// 다익스트라 실행
107+
static int dijkstra() {
108+
PriorityQueue<Node> q = new PriorityQueue<Node>();
109+
110+
boolean[] v = new boolean[N * N];
111+
112+
// 첫 번째 문에서 출발
113+
int start = door.get(0);
114+
115+
q.add(new Node(start, 0));
116+
117+
int result = 0;
118+
119+
while(!q.isEmpty()) {
120+
Node current = q.poll();
121+
122+
if(v[current.e]) continue;
123+
v[current.e] = true;
124+
125+
// 두 번째 문에 도달했다면 끝내기
126+
int cr = current.e / N, cc = current.e % N;
127+
if((cr == door.get(1) / N) && (cc == door.get(1) % N)) {
128+
result = current.mirrorCnt;
129+
break;
130+
}
131+
132+
// 거울의 개수가 작아질 수 있도록 해야 됨
133+
for(int next: adj[current.e]) {
134+
135+
int installMirrorCnt = current.mirrorCnt;
136+
137+
// 현재 위치의 좌표가 !이라면 거울의 개수를 늘려야 됨
138+
if(map[cr][cc] == '!') installMirrorCnt += 1;
139+
140+
q.add(new Node(next, installMirrorCnt));
141+
}
142+
}
143+
144+
return result;
145+
}
146+
147+
static boolean check(int r, int c) {
148+
return r >= 0 && r < N && c >= 0 && c < N;
149+
}
150+
}

‎BOJ/1000-5000번/DH_2931.java

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import java.io.*;
2+
import java.util.*;
3+
4+
/*
5+
* 가스관
6+
*/
7+
8+
public class DH_2931 {
9+
static final int U = 0, L = 1, D = 2, R = 3;
10+
static int[] dr = {-1, 0, 1, 0}, dc = {0, -1, 0, 1};
11+
static class Point {
12+
int r, c;
13+
public Point(int r, int c) {
14+
this.r = r;
15+
this.c = c;
16+
}
17+
}
18+
static Point start, end;
19+
static char[][] map;
20+
static Point point;
21+
static char[] blocks = {'|', '-', '+', '1', '2', '3', '4'};
22+
static StringBuilder sb = new StringBuilder();
23+
24+
public static void main(String[] args) throws Exception {
25+
initInput();
26+
solution();
27+
}
28+
29+
static void solution() {
30+
31+
// setPoint[0][1]: 블록 설치해야 되는 위치 (r, c)
32+
// setPoint[2]: M에서 출발할 때 어느 방향으로 가야 되는지
33+
int[] setPoint = getPoint();
34+
35+
char type = 0; // 무슨 타입 블록인지
36+
int d = setPoint[2]; // M이 처음 시작하는 방향
37+
38+
for(int k = 0; k < 7; k++) { // 블록을 설치해야 되는 위치에 모든 타입의 블록을 놓아봄
39+
40+
char block = blocks[k];
41+
42+
map[setPoint[0]][setPoint[1]] = block;
43+
44+
int nr = start.r + dr[d]; // M 직후 지점
45+
int nc = start.c + dc[d]; // M 직후 지점
46+
47+
// 현재 방향이 d이고, 다음 블록이 map[nr][nc]일 때
48+
// map[nr][nc]에서 나아가는 방향 정보
49+
int dir = getDir(nr, nc, d);
50+
dfs(nr, nc, dir);
51+
52+
// dfs를 수행하며 블록을 따라 갔을 때, 끝점에 도달한다면 block타입 블록을 설치해야 됨
53+
if(point.r == end.r && point.c == end.c) {
54+
type = block;
55+
break;
56+
}
57+
}
58+
sb.append(setPoint[0] + 1).append(" " ).append(setPoint[1] + 1).append(" ").append(type);
59+
System.out.println(sb);
60+
}
61+
62+
static void dfs(int r, int c, int cd) {
63+
64+
// 없어진 블록이거나, 끝 지점이라면 dfs 끝내기
65+
if(map[r][c] == '.' || map[r][c] == 'Z') {
66+
point = new Point(r, c);
67+
return;
68+
}
69+
70+
if(cd == -1) return; // 유효하지 않은 방향정보라면 끝내기
71+
72+
int nr = r + dr[cd];
73+
int nc = c + dc[cd];
74+
75+
if(!check(nr, nc)) return; // 범위를 벗어난다면 끝내기
76+
77+
int nd = getDir(nr, nc, cd);
78+
dfs(nr, nc, nd);
79+
}
80+
81+
// M에서 출발할 때, 어떤 방향을 바라보며 이동하는지와 없어진 블럭의 정보 찾기
82+
static int[] getPoint() {
83+
int dir = 0;
84+
85+
for(int d = 0; d < 4; d++) {
86+
int nr = start.r + dr[d];
87+
int nc = start.c + dc[d];
88+
89+
// 이 때, M 옆에 바로 Z가 있을 수도 있으니 map[nr][nc]가 Z인 경우도 제외해줘야 됨!!!
90+
if(!check(nr, nc) || map[nr][nc] == '.' || map[nr][nc] == 'Z') continue;
91+
92+
dir = d;
93+
dfs(nr, nc, getDir(nr, nc, d));
94+
}
95+
96+
return new int[] {point.r, point.c, dir};
97+
}
98+
99+
// 현재 지점에서 나아가는 방향이 d이고, 다음 좌표가 (r, c)일 때
100+
// (r, c)에서의 방향
101+
static int getDir(int r, int c, int d) {
102+
char ch = map[r][c];
103+
104+
if(ch =='.') return -1;
105+
int cd = -1;
106+
107+
if(d == U) {
108+
if(ch == '|') cd = U;
109+
else if(ch == '+') cd = U;
110+
else if(ch == '1') cd = R;
111+
else if(ch == '4') cd = L;
112+
}
113+
114+
if(d == L) {
115+
if(ch == '-') cd = L;
116+
else if(ch == '+') cd = L;
117+
else if(ch == '1') cd = D;
118+
else if(ch == '2') cd = U;
119+
}
120+
121+
if(d == D) {
122+
if(ch == '|') cd = D;
123+
else if(ch == '+') cd = D;
124+
else if(ch == '2') cd = R;
125+
else if(ch == '3') cd = L;
126+
}
127+
128+
if(d == R) {
129+
if(ch == '-') cd = R;
130+
else if(ch == '+') cd = R;
131+
else if(ch == '3') cd = U;
132+
else if(ch == '4') cd = D;
133+
}
134+
135+
return cd;
136+
}
137+
138+
static boolean check(int r, int c) {
139+
return r >= 0 && r < map.length && c >= 0 && c < map[0].length;
140+
}
141+
static void initInput() throws Exception {
142+
143+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
144+
StringTokenizer st = new StringTokenizer(br.readLine());
145+
146+
int R = Integer.parseInt(st.nextToken());
147+
int C = Integer.parseInt(st.nextToken());
148+
149+
map = new char[R][C];
150+
151+
for(int r = 0; r < R; r++) {
152+
map[r] = br.readLine().toCharArray();
153+
for(int c = 0; c < C; c++) {
154+
155+
if(map[r][c] == 'M') start = new Point(r, c);
156+
if(map[r][c] == 'Z') end = new Point(r, c);
157+
158+
if(map[r][c] == 'M' || map[r][c] == 'Z' || map[r][c] == '.') continue;
159+
}
160+
}
161+
162+
}
163+
}

‎BOJ/1000-5000번/DH_3151.java

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import java.io.*;
2+
import java.util.*;
3+
4+
/*
5+
* 합이 0
6+
*/
7+
8+
public class DH_3151 {
9+
public static void main(String[] args) throws Exception {
10+
11+
System.setIn(new FileInputStream("./input/BOJ3151.txt"));
12+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
13+
StringTokenizer st;
14+
15+
int N = Integer.parseInt(br.readLine());
16+
st = new StringTokenizer(br.readLine());
17+
18+
int[] arr = new int[N];
19+
for(int i = 0; i < arr.length; i++) arr[i] = Integer.parseInt(st.nextToken());
20+
21+
Arrays.sort(arr);
22+
23+
long result = 0; // 10000C3은 int 범위를 벗어나기 때문에 long으로 선언
24+
25+
for(int i = 0; i < arr.length - 2; i++) {
26+
for(int j = i + 1; j < arr.length - 1; j++) {
27+
28+
// i와 j가 정해졌다면 세 번째 idx에 대해 이분탐색 진행
29+
// idx가 가능한 범위에서 upperbound와 lowerbound를 구해서 합이 0이 되는 경우 구하기
30+
int s = j + 1, e = arr.length - 1;
31+
32+
int sumFirstAndSecond = arr[i] + arr[j];
33+
34+
int upper = getUpperBound(arr, sumFirstAndSecond, s, e);
35+
int lower = getLowerBound(arr, sumFirstAndSecond, s, e);
36+
37+
if(sumFirstAndSecond + arr[upper] != 0) continue;
38+
39+
result += upper - lower + 1;
40+
}
41+
}
42+
43+
System.out.println(result);
44+
}
45+
46+
// s와 e 이내에서 sumFirstAndSecond와 더했을 때 0이 되는 수(lowerbound) 구하기
47+
static int getLowerBound(int[] arr, int sumFirstAndSecond, int s, int e) {
48+
int os = s, oe = e;
49+
50+
while(os <= s && e <= oe && s <= e) {
51+
int m = (s + e) / 2;
52+
53+
int sum = sumFirstAndSecond + arr[m];
54+
55+
if(sum < 0) s = m + 1;
56+
else e = m - 1;
57+
}
58+
59+
return s;
60+
}
61+
62+
// s와 e 이내에서 sumFirstAndSecond와 더했을 때 0이 되는 수(upperbound) 구하기
63+
static int getUpperBound(int[] arr, int sumFirstAndSecond, int s, int e) {
64+
int os = s, oe = e;
65+
66+
while(os <= s && e <= oe && s <= e) {
67+
int m = (s + e) / 2;
68+
69+
int sum = sumFirstAndSecond + arr[m];
70+
71+
if(sum <= 0) s = m + 1;
72+
else e = m - 1;
73+
}
74+
75+
return e;
76+
}
77+
}

0 commit comments

Comments
(0)

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