diff --git a/week1/.gitkeep b/week1/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/week1/.gitkeep @@ -0,0 +1 @@ + diff --git a/week10/.gitkeep b/week10/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/week10/.gitkeep @@ -0,0 +1 @@ + diff --git a/week10/BOJ11403.java b/week10/BOJ11403.java new file mode 100644 index 0000000..1328cd2 --- /dev/null +++ b/week10/BOJ11403.java @@ -0,0 +1,46 @@ +import java.io.*; +import java.util.*; + +public class BOJ11403 { + + public static void main(String[] args) throws Exception{ + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + int N = Integer.parseInt(br.readLine()); + + int[][] graph = new int[N][N]; + + for (int i=0; i q = new LinkedList<>(); + q.add(i); + + while(!q.isEmpty()) { + int current = q.poll(); + + for (int j=0; j { + int u, v, w; + + Edge(int u, int v, int w) { + this.u = u; + this.v = v; + this.w = w; + } + + @Override + public int compareTo(Edge other) { + return this.w - other.w; + } + } + + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + int V = Integer.parseInt(st.nextToken()); + int E = Integer.parseInt(st.nextToken()); + + // 간선 정보를 저장할 리스트 + List edges = new ArrayList<>(); + for (int i = 0; i < E; i++) { + st = new StringTokenizer(br.readLine()); + int u = Integer.parseInt(st.nextToken()); + int v = Integer.parseInt(st.nextToken()); + int w = Integer.parseInt(st.nextToken()); + edges.add(new Edge(u, v, w)); + } + + // 간선을 가중치 기준으로 오름차순 정렬 + Collections.sort(edges); + + // 각 정점의 부모를 자기 자신으로 초기화 + parent = new int[V + 1]; + for (int i = 1; i <= V; i++) { + parent[i] = i; + } + + long result = 0; // MST의 총 가중치를 저장할 변수 + int count = 0; // 선택된 간선의 수 + + for (Edge edge : edges) { + // 두 정점을 연결했을 때 사이클이 생기지 않으면 union 수행 + if (union(edge.u, edge.v)) { + result += edge.w; + count++; + // 간선 V-1개 선택되면 MST 완성됨 + if (count == V - 1) break; + } + } + + System.out.println(result); + } + + public static int find(int a) { + if (parent[a] != a) { + parent[a] = find(parent[a]); + } + return parent[a]; + } + + // 두 정점을 합칠 수 있으면 true, 사이클 형성 시 false 반환 + public static boolean union(int a, int b) { + int rootA = find(a); + int rootB = find(b); + if (rootA == rootB) return false; + parent[rootB] = rootA; + return true; + } +} \ No newline at end of file diff --git a/week10/BOJ1238.java b/week10/BOJ1238.java new file mode 100644 index 0000000..ce13375 --- /dev/null +++ b/week10/BOJ1238.java @@ -0,0 +1,83 @@ +import java.io.*; +import java.util.*; + +public class BOJ1238 { + static class Edge implements Comparable { + int to, weight; + Edge(int to, int weight) { + this.to = to; + this.weight = weight; + } + public int compareTo(Edge o) { + return this.weight - o.weight; + } + } + + static int INF = Integer.MAX_VALUE; + + public static int[] dijkstra(int start, ArrayList[] graph, int n) { + int[] dist = new int[n + 1]; + Arrays.fill(dist, INF); + dist[start] = 0; + PriorityQueue pq = new PriorityQueue<>(); + pq.add(new Edge(start, 0)); + + while (!pq.isEmpty()) { + Edge current = pq.poll(); + int cur = current.to; + int curDist = current.weight; + + // 현재 저장된 거리보다 큰 경우 스킵 + if (curDist > dist[cur]) continue; + + for (Edge edge : graph[cur]) { + int next = edge.to; + int nextDist = curDist + edge.weight; + if (nextDist < dist[next]) { + dist[next] = nextDist; + pq.add(new Edge(next, nextDist)); + } + } + } + return dist; + } + + 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()); // 간선 개수 + int X = Integer.parseInt(st.nextToken()); // 파티가 열리는 정점 + + // 원래 그래프와 간선을 뒤집은 역방향 그래프 생성 + ArrayList[] graph = new ArrayList[N + 1]; + ArrayList[] revGraph = new ArrayList[N + 1]; + for (int i = 1; i <= N; i++) { + graph[i] = new ArrayList<>(); + revGraph[i] = new ArrayList<>(); + } + + for (int i = 0; i < M; i++) { + st = new StringTokenizer(br.readLine()); + int from = Integer.parseInt(st.nextToken()); + int to = Integer.parseInt(st.nextToken()); + int weight = Integer.parseInt(st.nextToken()); + graph[from].add(new Edge(to, weight)); + // 역방향 그래프: 도착지를 from으로, from을 to로 저장 + revGraph[to].add(new Edge(from, weight)); + } + + // X에서 각 정점까지 최단 경로 + int[] distFromX = dijkstra(X, graph, N); + // 각 정점에서 x로 가는 최단 경로 + int[] distToX = dijkstra(X, revGraph, N); + + // 모든 정점에 대해 왕복 시간의 최댓값 계산 + int maxTime = 0; + for (int i = 1; i <= N; i++) { + maxTime = Math.max(maxTime, distFromX[i] + distToX[i]); + } + + System.out.println(maxTime); + } +} \ No newline at end of file diff --git a/week10/BOJ14940.java b/week10/BOJ14940.java new file mode 100644 index 0000000..c929cb0 --- /dev/null +++ b/week10/BOJ14940.java @@ -0,0 +1,88 @@ +import java.io.*; +import java.util.*; + +public class BOJ14940 { + static int N, M, startX, startY; + static boolean[][] visited; + static int[][] map; + static int[][] result; + + static int[] dx = {-1, 1, 0, 0}; + static int[] dy = {0, 0, -1, 1}; + + public static void main(String[] args) throws Exception{ + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + StringBuilder sb = new StringBuilder(); + + N = Integer.parseInt(st.nextToken()); + M = Integer.parseInt(st.nextToken()); + + map = new int[N][M]; + visited = new boolean[N][M]; + result = new int[N][M]; + + for (int i=0; i q = new LinkedList<>(); + q.offer(new int[] {startX, startY}); + result[startX][startY] = 0; + visited[startX][startY] = true; + + while(!q.isEmpty()) { + int[] current = q.poll(); + for (int i=0; i<4; i++) { + int x = current[0]+dx[i]; + int y = current[1]+dy[i]; + + // 범위 벗어나거나, 이미 방문했을 경우 + if (!isOk(x, y) || visited[x][y]) continue; + + visited[x][y] = true; + result[x][y] = result[current[0]][current[1]]+1; + q.offer(new int[] {x, y}); + } + } + } + + + static boolean isOk(int x, int y) { // 범위 체크 + if (x<0 || y<0 || x>=N || y >=M) return false; + return true; + } +} \ No newline at end of file diff --git a/week10/BOJ16928.java b/week10/BOJ16928.java new file mode 100644 index 0000000..17a8c3c --- /dev/null +++ b/week10/BOJ16928.java @@ -0,0 +1,53 @@ +import java.io.*; +import java.util.*; + +public class BOJ16928 { + 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()); + + int[] move = new int[101]; + boolean[] visited = new boolean[101]; + + for (int i=0; i q = new LinkedList<>(); + q.add(new int[] {1, 0}); + visited[1] = true; + + while (!q.isEmpty()) { + int[] current = q.poll(); + + if (current[0] == 100) { // 100까지 도달! + System.out.println(current[1]); + return; + } + + for (int i=1; i<7; i++) { + int next = current[0] + i; + + // 100 넘어가거나 방문한 곳이면 continue + if (next > 100 || visited[next]) continue; + + if (move[next] != 0) { // 뱀, 사다리 중 하나이면 + next = move[next]; // 해당 값으로 이동 + } + + q.add(new int[] {next, current[1]+1}); + visited[next] = true; + } + } + + System.out.println(); + } +} \ No newline at end of file diff --git a/week11/.gitkeep b/week11/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/week11/.gitkeep @@ -0,0 +1 @@ + diff --git a/week11/BOJ11727.java b/week11/BOJ11727.java new file mode 100644 index 0000000..cda6846 --- /dev/null +++ b/week11/BOJ11727.java @@ -0,0 +1,28 @@ +import java.io.*; + +public class BOJ11727 { + static int N; + static int[] dp; + + public static void main(String[] args) throws Exception{ + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + + N = Integer.parseInt(br.readLine()); + + if (N == 1) { + System.out.println(1); + return; + } + + dp = new int[N+1]; + dp[1] = 1; + dp[2] = 3; + + // 마지막 2*2 타일을 채우는 경우(2가지) + 2*1 타일을 채우는 경우 + for (int i=3; i<=N; i++) { + dp[i] = (dp[i-2]*2+dp[i-1]) % 10007; + } + + System.out.println(dp[N]); + } +} \ No newline at end of file diff --git a/week11/BOJ1261.java b/week11/BOJ1261.java new file mode 100644 index 0000000..1a65479 --- /dev/null +++ b/week11/BOJ1261.java @@ -0,0 +1,70 @@ +import java.io.*; +import java.util.*; + +public class BOJ1261 { + static int N, M; + static int[][] map; + static int[][] wallCnt; + + // 상 하 좌 우 + static int[] dx = {-1, 1, 0, 0}; + static int[] dy = {0, 0, -1, 1}; + + public static void main(String[] args) throws Exception{ + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + M = Integer.parseInt(st.nextToken()); + N = Integer.parseInt(st.nextToken()); + + map = new int[N][M]; + wallCnt = new int[N][M]; + + for (int i=0; i d = new LinkedList<>(); + d.add(new int[]{0, 0}); + wallCnt[0][0] = 0; + + while (!d.isEmpty()){ + int[] current = d.poll(); + int x = current[0]; + int y = current[1]; + + for (int i=0; i<4; i++){ + int nx = x + dx[i]; + int ny = y + dy[i]; + + if (!isOK(nx, ny)) continue; + + // 이번 경로로 (nx, ny)까지 도달했을 때의 벽의 개수 + int wall = wallCnt[x][y] + map[nx][ny]; + + // 그 개수가 기존 (nx, ny)까지의 벽의 개수보다 작다면 + if (wall < wallCnt[nx][ny]){ + wallCnt[nx][ny] = wall; // 최솟값이므로 갱신 + if (map[nx][ny] == 0){ + d.addFirst(new int[]{nx, ny}); + } else { + d.addLast(new int[]{nx, ny}); + } // map[nx][ny]가 0이면 deque의 앞에, 1이면 뒤에 삽입하여 55~59 Line 연산 횟수 줄임 + } + } + } + } + + static boolean isOK(int x, int y){ + if (x<0 || y<0 || x>=N || y>=M) return false; + return true; + } +} \ No newline at end of file diff --git a/week11/BOJ12865.java b/week11/BOJ12865.java new file mode 100644 index 0000000..ebccca8 --- /dev/null +++ b/week11/BOJ12865.java @@ -0,0 +1,42 @@ +import java.io.*; +import java.util.*; + +public class BOJ12865 { + static int N, K; + static int[] weight, value; + static int[][] dp; + + 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()); + K = Integer.parseInt(st.nextToken()); + + weight = new int[N+1]; + value = new int[N+1]; + + + for (int i=1; i<=N; i++) { + st = new StringTokenizer(br.readLine()); + + weight[i] = Integer.parseInt(st.nextToken()); + value[i] = Integer.parseInt(st.nextToken()); + } + + dp = new int[N+1][K+1]; + + for (int i=1; i<=N; i++) { + for (int j=1; j<=K; j++) { + dp[i][j] = dp[i-1][j]; + + if (j-weight[i]>=0) { // j가 weight[i]보다 같거나 크면 + // 기존 값 vs i번째 물건의 무게만큼 뺀 것의 최댓값(dp)에 i번째 물건의 가치를 더한 값 중 큰 것 + dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i]); + } + } + } + + System.out.println(dp[N][K]); + } +} \ No newline at end of file diff --git a/week11/BOJ2151.java b/week11/BOJ2151.java new file mode 100644 index 0000000..4b28ab3 --- /dev/null +++ b/week11/BOJ2151.java @@ -0,0 +1,104 @@ +import java.io.*; +import java.util.*; + +public class BOJ2151 { + static int N; + static char[][] grid; + static int[][][] dist; + + // 상 우 하 좌 + static int[] dx = {-1, 0, 1, 0}; + static int[] dy = {0, 1, 0, -1}; + + static class State implements Comparable { + int x, y, d, cnt; + public State(int x, int y, int d, int cnt) { + this.x = x; this.y = y; this.d = d; this.cnt = cnt; + } + public int compareTo(State o) { + return this.cnt - o.cnt; + } + } + + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + N = Integer.parseInt(br.readLine()); + grid = new char[N][N]; + List doorList = new ArrayList<>(); + + for (int i = 0; i < N; i++){ + String line = br.readLine(); + grid[i] = line.toCharArray(); + for (int j = 0; j < N; j++){ + if (grid[i][j] == '#') { + doorList.add(new int[]{i, j}); + } + } + } + + // doorList의 첫번째: 시작 문, 두번째: 도착 문 + int startX = doorList.get(0)[0]; + int startY = doorList.get(0)[1]; + int endX = doorList.get(1)[0]; + int endY = doorList.get(1)[1]; + + dist = new int[N][N][4]; + for (int i = 0; i < N; i++){ + for (int j = 0; j < N; j++){ + Arrays.fill(dist[i][j], Integer.MAX_VALUE); + } + } + + PriorityQueue pq = new PriorityQueue<>(); + + // 시작 문에서는 어떤 방향으로도 진행 가능하므로 4방향 초기화 + for (int d = 0; d < 4; d++){ + dist[startX][startY][d] = 0; + pq.offer(new State(startX, startY, d, 0)); + } + + while (!pq.isEmpty()){ + State cur = pq.poll(); + int x = cur.x, y = cur.y, d = cur.d, cnt = cur.cnt; + if (cnt > dist[x][y][d]) continue; + + // 도착 문에 도달하면 정답 출력 + if (x == endX && y == endY) { + System.out.println(cnt); + return; + } + + // 현재 방향 그대로 전진 + int nx = x + dx[d]; + int ny = y + dy[d]; + if (isOK(nx, ny) && grid[nx][ny] != '*') { + if (cnt < dist[nx][ny][d]){ + dist[nx][ny][d] = cnt; + pq.offer(new State(nx, ny, d, cnt)); + } + } + + // 현재 위치가 거울을 설치할 수 있는 곳이라면, 좌우로 방향 전환 가능 + if (grid[x][y] == '!') { + int left = (d + 3) % 4; + int right = (d + 1) % 4; + if (isOK(x + dx[left], y + dy[left]) && grid[x + dx[left]][y + dy[left]] != '*') { + if (cnt + 1 < dist[x][y][left]) { + dist[x][y][left] = cnt + 1; + pq.offer(new State(x, y, left, cnt + 1)); + } + } + if (isOK(x + dx[right], y + dy[right]) && grid[x + dx[right]][y + dy[right]] != '*') { + if (cnt + 1 < dist[x][y][right]) { + dist[x][y][right] = cnt + 1; + pq.offer(new State(x, y, right, cnt + 1)); + } + } + } + } + } + + static boolean isOK(int x, int y){ + return x >= 0 && y >= 0 && x < N && y < N; + } +} \ No newline at end of file diff --git a/week11/BOJ9251.java b/week11/BOJ9251.java new file mode 100644 index 0000000..6ec92a5 --- /dev/null +++ b/week11/BOJ9251.java @@ -0,0 +1,35 @@ +import java.io.*; + +public class BOJ9251 { + static char[] A, B; + static int[][] dp; + + public static void main(String[] args) throws Exception{ + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + + String a = br.readLine(); + String b = br.readLine(); + + dp = new int[a.length()+1][b.length()+1]; + A = new char[a.length()+1]; + B = new char[b.length()+1]; + + for (int i=1; i<=a.length(); i++) { + A[i] = a.charAt(i-1); + } + for (int i=1; i<=b.length(); i++) { + B[i] = b.charAt(i-1); + } + + for (int i=1; i<=a.length(); i++) { + for (int j=1; j<=b.length(); j++) { + // 두 문자가 같은 경우 이전까지의 공통 수열 길이에 +1 + if (A[i] == B[j]) dp[i][j] = dp[i-1][j-1]+1; + // 다를 경우 dp[i][j-1]과 dp[i-1][j] 중 더 큰 값 + else dp[i][j] = Math.max(dp[i][j-1], dp[i-1][j]); + } + } + + System.out.println(dp[a.length()][b.length()]); + } +} \ No newline at end of file diff --git a/week12/.gitkeep b/week12/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/week12/.gitkeep @@ -0,0 +1 @@ + diff --git a/week12/BOJ11727.java b/week12/BOJ11727.java new file mode 100644 index 0000000..cda6846 --- /dev/null +++ b/week12/BOJ11727.java @@ -0,0 +1,28 @@ +import java.io.*; + +public class BOJ11727 { + static int N; + static int[] dp; + + public static void main(String[] args) throws Exception{ + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + + N = Integer.parseInt(br.readLine()); + + if (N == 1) { + System.out.println(1); + return; + } + + dp = new int[N+1]; + dp[1] = 1; + dp[2] = 3; + + // 마지막 2*2 타일을 채우는 경우(2가지) + 2*1 타일을 채우는 경우 + for (int i=3; i<=N; i++) { + dp[i] = (dp[i-2]*2+dp[i-1]) % 10007; + } + + System.out.println(dp[N]); + } +} \ No newline at end of file diff --git a/week12/BOJ1261.java b/week12/BOJ1261.java new file mode 100644 index 0000000..1a65479 --- /dev/null +++ b/week12/BOJ1261.java @@ -0,0 +1,70 @@ +import java.io.*; +import java.util.*; + +public class BOJ1261 { + static int N, M; + static int[][] map; + static int[][] wallCnt; + + // 상 하 좌 우 + static int[] dx = {-1, 1, 0, 0}; + static int[] dy = {0, 0, -1, 1}; + + public static void main(String[] args) throws Exception{ + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + M = Integer.parseInt(st.nextToken()); + N = Integer.parseInt(st.nextToken()); + + map = new int[N][M]; + wallCnt = new int[N][M]; + + for (int i=0; i d = new LinkedList<>(); + d.add(new int[]{0, 0}); + wallCnt[0][0] = 0; + + while (!d.isEmpty()){ + int[] current = d.poll(); + int x = current[0]; + int y = current[1]; + + for (int i=0; i<4; i++){ + int nx = x + dx[i]; + int ny = y + dy[i]; + + if (!isOK(nx, ny)) continue; + + // 이번 경로로 (nx, ny)까지 도달했을 때의 벽의 개수 + int wall = wallCnt[x][y] + map[nx][ny]; + + // 그 개수가 기존 (nx, ny)까지의 벽의 개수보다 작다면 + if (wall < wallCnt[nx][ny]){ + wallCnt[nx][ny] = wall; // 최솟값이므로 갱신 + if (map[nx][ny] == 0){ + d.addFirst(new int[]{nx, ny}); + } else { + d.addLast(new int[]{nx, ny}); + } // map[nx][ny]가 0이면 deque의 앞에, 1이면 뒤에 삽입하여 55~59 Line 연산 횟수 줄임 + } + } + } + } + + static boolean isOK(int x, int y){ + if (x<0 || y<0 || x>=N || y>=M) return false; + return true; + } +} \ No newline at end of file diff --git a/week12/BOJ12865.java b/week12/BOJ12865.java new file mode 100644 index 0000000..39c57b8 --- /dev/null +++ b/week12/BOJ12865.java @@ -0,0 +1,39 @@ +import java.io.*; +import java.util.*; + +public class BOJ12865 { + + 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 K = Integer.parseInt(st.nextToken()); + + int[] weight = new int[N+1]; + int[] value = new int[N+1]; + + for (int i=1; i { + int x, y, d, cnt; + public State(int x, int y, int d, int cnt) { + this.x = x; this.y = y; this.d = d; this.cnt = cnt; + } + public int compareTo(State o) { + return this.cnt - o.cnt; + } + } + + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + N = Integer.parseInt(br.readLine()); + grid = new char[N][N]; + List doorList = new ArrayList<>(); + + for (int i = 0; i < N; i++){ + String line = br.readLine(); + grid[i] = line.toCharArray(); + for (int j = 0; j < N; j++){ + if (grid[i][j] == '#') { + doorList.add(new int[]{i, j}); + } + } + } + + // doorList의 첫번째: 시작 문, 두번째: 도착 문 + int startX = doorList.get(0)[0]; + int startY = doorList.get(0)[1]; + int endX = doorList.get(1)[0]; + int endY = doorList.get(1)[1]; + + dist = new int[N][N][4]; + for (int i = 0; i < N; i++){ + for (int j = 0; j < N; j++){ + Arrays.fill(dist[i][j], Integer.MAX_VALUE); + } + } + + PriorityQueue pq = new PriorityQueue<>(); + + // 시작 문에서는 어떤 방향으로도 진행 가능하므로 4방향 초기화 + for (int d = 0; d < 4; d++){ + dist[startX][startY][d] = 0; + pq.offer(new State(startX, startY, d, 0)); + } + + while (!pq.isEmpty()){ + State cur = pq.poll(); + int x = cur.x, y = cur.y, d = cur.d, cnt = cur.cnt; + if (cnt > dist[x][y][d]) continue; + + // 도착 문에 도달하면 정답 출력 + if (x == endX && y == endY) { + System.out.println(cnt); + return; + } + + // 현재 방향 그대로 전진 + int nx = x + dx[d]; + int ny = y + dy[d]; + if (isOK(nx, ny) && grid[nx][ny] != '*') { + if (cnt < dist[nx][ny][d]){ + dist[nx][ny][d] = cnt; + pq.offer(new State(nx, ny, d, cnt)); + } + } + + // 현재 위치가 거울을 설치할 수 있는 곳이라면, 좌우로 방향 전환 가능 + if (grid[x][y] == '!') { + int left = (d + 3) % 4; + int right = (d + 1) % 4; + if (isOK(x + dx[left], y + dy[left]) && grid[x + dx[left]][y + dy[left]] != '*') { + if (cnt + 1 < dist[x][y][left]) { + dist[x][y][left] = cnt + 1; + pq.offer(new State(x, y, left, cnt + 1)); + } + } + if (isOK(x + dx[right], y + dy[right]) && grid[x + dx[right]][y + dy[right]] != '*') { + if (cnt + 1 < dist[x][y][right]) { + dist[x][y][right] = cnt + 1; + pq.offer(new State(x, y, right, cnt + 1)); + } + } + } + } + } + + static boolean isOK(int x, int y){ + return x >= 0 && y >= 0 && x < N && y < N; + } +} \ No newline at end of file diff --git a/week12/BOJ9251.java b/week12/BOJ9251.java new file mode 100644 index 0000000..e69de29 diff --git a/week13/.gitkeep b/week13/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/week13/.gitkeep @@ -0,0 +1 @@ + diff --git a/week13/BOJ1629.java b/week13/BOJ1629.java new file mode 100644 index 0000000..057ec0f --- /dev/null +++ b/week13/BOJ1629.java @@ -0,0 +1,26 @@ +import java.io.*; +import java.util.*; + +public class BOJ1629 { + public static void main(String[] args) throws Exception{ + BufferedReader br = new BufferedReader(new InputStreamReader((System.in))); + StringTokenizer st = new StringTokenizer(br.readLine()); + + int A = Integer.parseInt(st.nextToken()); + int B = Integer.parseInt(st.nextToken()); + int C = Integer.parseInt(st.nextToken()); + + System.out.println(modPow(A, B, C)); + } + + // mod 연산의 성질 활용 + static long modPow(int a, int b, int m) { + if (b == 0) return 1; + long half = modPow(a, b / 2, m); + long result = (half * half) % m; + if (b % 2 == 1) { + result = (result * a) % m; + } + return result; + } +} \ No newline at end of file diff --git a/week13/BOJ1918.java b/week13/BOJ1918.java new file mode 100644 index 0000000..b47ee06 --- /dev/null +++ b/week13/BOJ1918.java @@ -0,0 +1,43 @@ +import java.io.*; +import java.util.*; + +public class BOJ1918 { + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + String infix = br.readLine(); + StringBuilder postfix = new StringBuilder(); + Deque oper = new LinkedList<>(); + + for (int i = 0; i < infix.length(); i++) { + char c = infix.charAt(i); + + if (c >= 'A' && c <= 'Z') { + postfix.append(c); + } else if (c == '(') { + oper.addLast(c); + } else if (c == ')') { + while (!oper.isEmpty() && oper.peekLast() != '(') { + postfix.append(oper.pollLast()); + } + oper.pollLast(); + } else { + while (!oper.isEmpty() && prec(oper.peekLast()) >= prec(c)) { + postfix.append(oper.pollLast()); + } + oper.addLast(c); + } + } + + while (!oper.isEmpty()) { + postfix.append(oper.pollLast()); + } + + System.out.println(postfix); + } + + public static int prec(char op) { + if (op == '+' || op == '-') return 1; + if (op == '*' || op == '/') return 2; + return 0; + } +} diff --git a/week13/BOJ9465.java b/week13/BOJ9465.java new file mode 100644 index 0000000..ec21094 --- /dev/null +++ b/week13/BOJ9465.java @@ -0,0 +1,32 @@ +import java.io.*; +import java.util.*; + +public class BOJ9465 { + public static void main(String[] args) throws Exception{ + BufferedReader br = new BufferedReader(new InputStreamReader((System.in))); + int T = Integer.parseInt(br.readLine()); + for (int t=0; t= 0; j -= 2) { + dp[i] += dp[j] * 2; + } + } + + System.out.println(dp[n]); + } +} diff --git a/week14/BOJ2629.java b/week14/BOJ2629.java new file mode 100644 index 0000000..0ed98be --- /dev/null +++ b/week14/BOJ2629.java @@ -0,0 +1,45 @@ +import java.io.*; +import java.util.*; + +public class BOJ2629 { + static boolean[][] dp; + static int[] weights; + static int N; + + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + N = Integer.parseInt(br.readLine()); + + weights = new int[N]; + StringTokenizer st = new StringTokenizer(br.readLine()); + for (int i = 0; i < N; i++) { + weights[i] = Integer.parseInt(st.nextToken()); + } + + dp = new boolean[N + 1][15001]; + solve(0, 0); + + int T = Integer.parseInt(br.readLine()); + st = new StringTokenizer(br.readLine()); + StringBuilder sb = new StringBuilder(); + while (T-- > 0) { + int target = Integer.parseInt(st.nextToken()); + if (target > 15000) sb.append("N "); + else sb.append(dp[N][target] ? "Y " : "N "); + } + + System.out.println(sb); + } + + static void solve(int idx, int weight) { + if (idx > N || dp[idx][weight]) return; + + dp[idx][weight] = true; + + if (idx == N) return; + + solve(idx + 1, weight); // 추 사용 안함 + solve(idx + 1, weight + weights[idx]); // 오른쪽에 놓음 + solve(idx + 1, Math.abs(weight - weights[idx])); // 왼쪽에 놓음 + } +} diff --git a/week16/.gitkeep b/week16/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/week16/.gitkeep @@ -0,0 +1 @@ + diff --git a/week16/BOJ10157.java b/week16/BOJ10157.java new file mode 100644 index 0000000..b1623f5 --- /dev/null +++ b/week16/BOJ10157.java @@ -0,0 +1,43 @@ +import java.io.*; +import java.util.*; + +public class BOJ10157 { + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + int C = Integer.parseInt(st.nextToken()); + int R = Integer.parseInt(st.nextToken()); + int K = Integer.parseInt(br.readLine()); + + if (K > C * R) { + System.out.println(0); + return; + } + + int[][] map = new int[R][C]; + int[] dx = {-1, 0, 1, 0}; // 상 우 하 좌 + int[] dy = {0, 1, 0, -1}; + + int x = R - 1, y = 0, dir = 0; + map[x][y] = 1; + + for (int i = 2; i <= K; i++) { + int nx = x + dx[dir]; + int ny = y + dy[dir]; + + // 범위 밖이거나 이미 앉은 자리면 방향 전환 + if (nx < 0 || ny < 0 || nx >= R || ny >= C || map[nx][ny] != 0) { + dir = (dir + 1) % 4; + nx = x + dx[dir]; + ny = y + dy[dir]; + } + + map[nx][ny] = i; + x = nx; + y = ny; + } + + System.out.println((y + 1) + " " + (R - x)); + } +} diff --git a/week16/BOJ1459.java b/week16/BOJ1459.java new file mode 100644 index 0000000..4b06285 --- /dev/null +++ b/week16/BOJ1459.java @@ -0,0 +1,40 @@ +import java.io.*; +import java.util.*; + +public class BOJ1459 { + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringTokenizer st = new StringTokenizer(br.readLine()); + + long x = Long.parseLong(st.nextToken()); + long y = Long.parseLong(st.nextToken()); + long w = Long.parseLong(st.nextToken()); + long s = Long.parseLong(st.nextToken()); + + long minCost = 0; + + // 모두 가로/세로로만 걷는 경우 + long case1 = (x + y) * w; + + // 모두 대각선으로만 걷는 경우 + long max = Math.max(x, y); + long min = Math.min(x, y); + long case2 = 0; + + if ((x + y) % 2 == 0) { + // 짝수라면 전부 대각선 이동 가능 + case2 = Math.max(x, y) * s; + } else { + // 아닐 경우 대각선으로 max-1 까지 가고, 남은 1칸은 w + case2 = (max - 1) * s + w; + } + + // min만큼 대각선 + 나머지는 직선 + long case3 = min * s + (max - min) * w; + + // 셋 중 최솟값 선택 + minCost = Math.min(case1, Math.min(case2, case3)); + + System.out.println(minCost); + } +} diff --git a/week16/BOJ2578.java b/week16/BOJ2578.java new file mode 100644 index 0000000..f18fe0b --- /dev/null +++ b/week16/BOJ2578.java @@ -0,0 +1,86 @@ +import java.io.*; +import java.util.*; + +public class BOJ2578 { + static int[][] board = new int[5][5]; + static boolean[][] marked = new boolean[5][5]; + + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + + // 빙고판 입력 + for (int i = 0; i < 5; i++) { + StringTokenizer st = new StringTokenizer(br.readLine()); + for (int j = 0; j < 5; j++) { + board[i][j] = Integer.parseInt(st.nextToken()); + } + } + + // 사회자가 부른 숫자 순서대로 처리 + int callCount = 0; + outer: + for (int i = 0; i < 5; i++) { + StringTokenizer st = new StringTokenizer(br.readLine()); + for (int j = 0; j < 5; j++) { + int num = Integer.parseInt(st.nextToken()); + callCount++; + mark(num); + if (countBingo() >= 3) { + System.out.println(callCount); + break outer; + } + } + } + } + + // 숫자 찾아 체크 + static void mark(int num) { + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 5; j++) { + if (board[i][j] == num) { + marked[i][j] = true; + return; + } + } + } + } + + // 빙고 줄 수 카운트 + static int countBingo() { + int count = 0; + + // 가로 + for (int i = 0; i < 5; i++) { + boolean bingo = true; + for (int j = 0; j < 5; j++) { + if (!marked[i][j]) bingo = false; + } + if (bingo) count++; + } + + // 세로 + for (int j = 0; j < 5; j++) { + boolean bingo = true; + for (int i = 0; i < 5; i++) { + if (!marked[i][j]) bingo = false; + } + if (bingo) count++; + } + + // 대각선 '\' + boolean diag1 = true; + for (int i = 0; i < 5; i++) { + if (!marked[i][i]) diag1 = false; + } + if (diag1) count++; + + // 대각선 '/' + boolean diag2 = true; + for (int i = 0; i < 5; i++) { + if (!marked[i][4 - i]) diag2 = false; + } + if (diag2) count++; + + return count; + } +}