-
Notifications
You must be signed in to change notification settings - Fork 4
[10주차] 백제완 #137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[10주차] 백제완 #137
Changes from 4 commits
803c47c
789d089
3361c01
01000fc
9649228
0ce486f
2077a9a
3a03a9c
0f1b290
113d960
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import java.util.Arrays; | ||
|
||
public class JW_1613 { | ||
|
||
public static void main(String[] args) throws Exception { | ||
int n = read(), k = read(); | ||
int[][] dist = new int[n + 1][n + 1]; | ||
// 상대적인 거리 초기화 | ||
for (int i = 0; i < n; i++) { | ||
int u = read(), v = read(); | ||
dist[u][v] = -1; | ||
dist[v][u] = 1; | ||
} | ||
// 플로이드 와샬 | ||
for (int p = 1; p < n + 1; p++) | ||
for (int i = 1; i < n + 1; i++) | ||
for (int j = 1; j < n + 1; j++) | ||
// i -> p의 상태를 이용하여 다음 값 결정 | ||
if (dist[i][p] != 0 && dist[i][p] == dist[p][j]) | ||
dist[i][j] = dist[i][p]; | ||
Comment on lines
+9
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dist에 진짜 떨어진 거리를 저장하는게 아니라 선후관계를 저장하면 되군요?,,,, 아하,,, !! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 맞습니다! 그래서 풀어보면 좋은 문제 리스트에 이 문제 넣어놨었는데 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이부분 질문이 있는데요!
이건 이해를 했어요.. 근데
제완님 위시리스트 같아서 참고했죠ᄒᄒ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오호 이거 진짜 똑똑한 생각인것 같아요!! 선후관계를 넣는 것!! 😮 |
||
int s = read(); | ||
StringBuilder sb = new StringBuilder(); | ||
while (s-- > 0) { | ||
sb.append(dist[read()][read()]).append("\n"); | ||
} | ||
System.out.println(sb); | ||
} | ||
|
||
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; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
public class JW_2096 { | ||
|
||
public static void main(String[] args) throws Exception { | ||
int n = read(); | ||
int[] maxDp = new int[3]; | ||
int[] minDp = new int[3]; | ||
for (int i = 0; i < 3; i++) { | ||
int p = read(); | ||
maxDp[i] = p; | ||
minDp[i] = p; | ||
} | ||
// DP: 현재 값으로 다음 값 결정하지 | ||
for (int i = 1; i < n; i++) { | ||
int[] next = { read(), read(), read() }; | ||
int[] nextMaxDp = new int[3]; | ||
int[] nextMinDp = new int[3]; | ||
|
||
// 가능한 범위 내에서 최댓값 찾기 | ||
nextMaxDp[0] = next[0] + Math.max(maxDp[0], maxDp[1]); | ||
nextMaxDp[1] = next[1] + Math.max(Math.max(maxDp[0], maxDp[1]), maxDp[2]); | ||
nextMaxDp[2] = next[2] + Math.max(maxDp[1], maxDp[2]); | ||
|
||
// 가능한 범위 내에서 최솟값 찾기 | ||
nextMinDp[0] = next[0] + Math.min(minDp[0], minDp[1]); | ||
nextMinDp[1] = next[1] + Math.min(Math.min(minDp[0], minDp[1]), minDp[2]); | ||
nextMinDp[2] = next[2] + Math.min(minDp[1], minDp[2]); | ||
|
||
// DP 배열 갱신 | ||
maxDp = nextMaxDp; | ||
minDp = nextMinDp; | ||
} | ||
StringBuilder sb = new StringBuilder(); | ||
sb.append(Math.max(maxDp[0], Math.max(maxDp[1], maxDp[2]))); | ||
sb.append(" ").append(Math.min(minDp[0], Math.min(minDp[1], minDp[2]))); | ||
System.out.println(sb); | ||
} | ||
|
||
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; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
import java.io.BufferedReader; | ||
import java.io.InputStreamReader; | ||
import java.util.ArrayList; | ||
|
||
public class JW_2955 { | ||
|
||
public static void main(String[] args) throws Exception { | ||
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); | ||
int[][] board = new int[9][9]; | ||
for (int i = 0; i < 9; i++) { | ||
String line = br.readLine(); | ||
for (int j = 0; j < 9; j++) | ||
if (Character.isDigit(line.charAt(j))) { | ||
board[i][j] = line.charAt(j) - '0'; | ||
} | ||
} | ||
// 갱신되는 숫자가 없을 때까지 반복 | ||
boolean playFlag = true; | ||
while (playFlag) { | ||
playFlag = false; | ||
// 각 숫자가 들어갈 수 있는 자리를 체크 | ||
for (int num = 1; num <= 9; num++) { | ||
// crossHatching을 이용하여 target이 들어갈 수 있는 자리들을 확인 | ||
boolean[][] checkBoard = crossHatching(board, num); | ||
// 잘못된 경우라면 에러 출력 | ||
if (!isValid(num, board, checkBoard)) { | ||
System.out.println("ERROR"); | ||
return; | ||
} | ||
// 각 서브 그리드 안에 숫자를 넣을 수 있는지 확인 | ||
for (int i = 0; i < 9; i++) | ||
if (putNumber(num, board, i, checkBoard)) | ||
playFlag = true; // 넣을 수 있다면 반복 | ||
} | ||
} | ||
System.out.println(printBoard(board)); | ||
} | ||
|
||
private static boolean[][] crossHatching(int[][] board, int target) { | ||
boolean[][] checkBoard = new boolean[9][9]; | ||
// 1. 이미 숫자가 존재함 | ||
for (int i = 0; i < 9; i++) | ||
for (int j = 0; j < 9; j++) | ||
if (board[i][j] != 0) | ||
checkBoard[i][j] = true; | ||
// 2. 타겟과 같은 숫자의 위치 | ||
for (int i = 0; i < 9; i++) | ||
for (int j = 0; j < 9; j++) | ||
if (board[i][j] == target) { | ||
check(checkBoard, i, j); | ||
} | ||
return checkBoard; | ||
} | ||
|
||
// 타겟(숫자)이 들어갈 수 있는지 확인하고 들어갈 자리가 한 곳이라면 삽입 | ||
private static boolean putNumber(int target, int[][] board, int boardNum, boolean[][] checkBoard) { | ||
ArrayList<int[]> arr = new ArrayList<>(); | ||
int sy = (boardNum / 3) * 3, sx = (boardNum % 3) * 3; | ||
for (int i = 0; i < 3; i++) { | ||
for (int j = 0; j < 3; j++) { | ||
int ny = sy + i; | ||
int nx = sx + j; | ||
if (!checkBoard[ny][nx]) | ||
arr.add(new int[] { ny, nx }); | ||
} | ||
} | ||
if (arr.size() == 1) { | ||
int y = arr.get(0)[0]; | ||
int x = arr.get(0)[1]; | ||
board[y][x] = target; | ||
check(checkBoard, y, x); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
// 해당 자리 기준으로 상하좌우, 서브그리드 체크 | ||
private static void check(boolean[][] checkBoard, int y, int x) { | ||
int sy = (y / 3) * 3; | ||
int sx = (x / 3) * 3; | ||
for (int i = 0; i < 3; i++) | ||
for (int j = 0; j < 3; j++) { | ||
checkBoard[sy + i][sx + j] = true; | ||
} | ||
for (int i = 0; i < 9; i++) { | ||
checkBoard[y][i] = true; | ||
checkBoard[i][x] = true; | ||
} | ||
} | ||
|
||
// 유효성 체크 | ||
private static boolean isValid(int target, int[][] board, boolean[][] checkBoard) { | ||
for (int i = 0; i < 9; i++) { | ||
int putCnt = 0; | ||
int numCnt = 0; | ||
int sy = (i / 3) * 3; | ||
int sx = (i % 3) * 3; | ||
for (int j = 0; j < 3; j++) | ||
for (int k = 0; k < 3; k++) { | ||
int ny = sy + j, nx = sx + k; | ||
if (board[ny][nx] == target) | ||
numCnt++; | ||
if (!checkBoard[ny][nx]) | ||
putCnt++; | ||
} | ||
// 서브그리드에 타겟과 동일한 숫자가 2개, 들어갈 자리가 없는데 타겟이 없을 경우 예외 | ||
if (numCnt > 1 || putCnt == 0 && numCnt == 0) | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
// 스도쿠 출력 | ||
private static String printBoard(int[][] board) { | ||
StringBuilder sb = new StringBuilder(); | ||
for (int i = 0; i < 9; i++) { | ||
for (int j = 0; j < 9; j++) | ||
if (board[i][j] == 0) | ||
sb.append("."); | ||
else | ||
sb.append(board[i][j]); | ||
sb.append("\n"); | ||
} | ||
return sb.toString(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import java.io.BufferedReader; | ||
import java.io.InputStreamReader; | ||
import java.util.ArrayDeque; | ||
import java.util.Deque; | ||
import java.util.StringTokenizer; | ||
|
||
public class JW_회전하는_빙하 { | ||
|
||
static int n, m, q; | ||
static int[][] board; // 빙하를 저장할 배열 | ||
static int[][] tempBoard; // 다음 빙하 결정에 영향을 주는 배열 | ||
static boolean[][] visited; | ||
static int maxCnt = 0; // 최대 군집의 크기 | ||
static int sum = 0; // 남은 빙하의 합 | ||
static int[] dy = { 0, 1, -1, 0 }; | ||
static int[] dx = { 1, 0, 0, -1 }; | ||
|
||
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 = (int) Math.pow(2, n); | ||
q = Integer.parseInt(st.nextToken()); | ||
board = new int[m][m]; | ||
for (int i = 0; i < m; i++) { | ||
st = new StringTokenizer(br.readLine()); | ||
for (int j = 0; j < m; j++) | ||
board[i][j] = Integer.parseInt(st.nextToken()); | ||
} | ||
int[] level = new int[q]; | ||
st = new StringTokenizer(br.readLine()); | ||
for (int i = 0; i < q; i++) | ||
level[i] = Integer.parseInt(st.nextToken()); | ||
for (int t = 0; t < q; t++) { | ||
// 레벨이 1이상인 경우에만 회전 | ||
if (level[t] > 0) | ||
rotate(level[t]); // 빙하의 회전 구현 | ||
melt(); // 빙하의 녹음 구현 | ||
} | ||
caclulate(); // 빙하의 최대 군집의 크기 계산 및 총합 계산 | ||
System.out.println(sum); | ||
System.out.println(maxCnt); | ||
} | ||
|
||
// 빙하의 회전 구현 | ||
private static void rotate(int l) { | ||
int M = (int) Math.pow(2, l); | ||
int N = (int) Math.pow(2, l - 1); | ||
tempBoard = new int[m][m]; | ||
for (int i = 0; i < m; i += M) { | ||
for (int j = 0; j < m; j += M) { | ||
// 각 꼭짓점을 기준으로 덩어리들이 움직임 | ||
move(i, j, N, 0); | ||
move(i, j + N, N, 1); | ||
move(i + N, j, N, 2); | ||
move(i + N, j + N, N, 3); | ||
} | ||
} | ||
for (int i = 0; i < m; i++) | ||
for (int j = 0; j < m; j++) | ||
board[i][j] = tempBoard[i][j]; | ||
} | ||
|
||
// 빙하의 움직임 구현 | ||
private static void move(int sy, int sx, int N, int dir) { | ||
for (int i = 0; i < N; i++) | ||
for (int j = 0; j < N; j++) { | ||
int y = (sy + i) + N * dy[dir]; | ||
int x = (sx + j) + N * dx[dir]; | ||
tempBoard[y][x] = board[sy + i][sx + j]; | ||
} | ||
} | ||
|
||
// 빙하의 녹음 구현 | ||
private static void melt() { | ||
tempBoard = new int[m][m]; | ||
for (int i = 0; i < m; i++) | ||
for (int j = 0; j < m; j++) | ||
if (board[i][j] > 0) { | ||
int cnt = 0; | ||
// 주변 빙하의 수 계산 | ||
for (int k = 0; k < 4; k++) { | ||
int y = i + dy[k]; | ||
int x = j + dx[k]; | ||
if (isValid(y, x) && board[y][x] > 0) | ||
cnt++; | ||
} | ||
// 3개 미만이면 빙하 감소 | ||
if (cnt < 3) | ||
tempBoard[i][j]--; | ||
} | ||
for (int i = 0; i < m; i++) | ||
for (int j = 0; j < m; j++) | ||
board[i][j] += tempBoard[i][j]; | ||
} | ||
|
||
// 군집 크기 및 총합 계산 | ||
private static void caclulate() { | ||
visited = new boolean[m][m]; | ||
for (int i = 0; i < m; i++) | ||
for (int j = 0; j < m; j++) | ||
if (!visited[i][j] && board[i][j] > 0) { | ||
// 빙하 군집의 크기를 계산하기 위한 BFS | ||
int cnt = bfs(i, j); | ||
maxCnt = Math.max(maxCnt, cnt); | ||
} | ||
} | ||
|
||
// BFS | ||
private static int bfs(int y, int x) { | ||
int cnt = 0; | ||
Deque<int[]> dq = new ArrayDeque<>(); | ||
dq.offer(new int[] { y, x }); | ||
while (!dq.isEmpty()) { | ||
int[] cur = dq.poll(); | ||
if (visited[cur[0]][cur[1]]) | ||
continue; | ||
visited[cur[0]][cur[1]] = true; | ||
cnt++; // 빙하 수 카운트 | ||
sum += board[cur[0]][cur[1]]; // 총 합 증가 | ||
for (int i = 0; i < 4; i++) { | ||
int ny = cur[0] + dy[i]; | ||
int nx = cur[1] + dx[i]; | ||
if (isValid(ny, nx) && !visited[ny][nx] && board[ny][nx] > 0) { | ||
dq.offer(new int[] { ny, nx }); | ||
} | ||
} | ||
} | ||
return cnt; | ||
} | ||
|
||
// 경계 체크 | ||
private static boolean isValid(int y, int x) { | ||
return 0 <= y && y < m && 0 <= x && x < m; | ||
} | ||
} |