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

[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

Merged
jewan100 merged 10 commits into GreatAlgorithm-Study:main from jewan100:main
Nov 17, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
10 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions BOJ/1000-5000번/JW_1613.java
View file Open in desktop
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dist에 진짜 떨어진 거리를 저장하는게 아니라 선후관계를 저장하면 되군요?,,,, 아하,,, !!

jewan100 reacted with thumbs up emoji
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞습니다! 그래서 풀어보면 좋은 문제 리스트에 이 문제 넣어놨었는데
제출돼서 반가웠어여 ᄏᄏᄏᄏ

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이부분 질문이 있는데요!
dist[i][p] == dist[p][j] i → j 로 경유 할때 왜 dist[i][p]dist[i][j] 로.. 들어가는건가요...!?

i → p와 p → j가 동일하다면 i → j도 동일한 상태를 가짐

이건 이해를 했어요.. 근데 dist[i][j] = dist[i][p]; 가 어떤 관계인지 잘 이해가 안가는데 설명해주실수있을까요?🥺


풀어보면 좋은 문제 리스트에 이 문제 넣어놨었는데

제완님 위시리스트 같아서 참고했죠ᄒᄒ

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아! dp[i]][j]에 들어가는 값은 dp[i][p]이든 dp[p][j]든 상관 없습니다!
어차피 같은 상태를 저장하고 있기 때문에 둘 중 아무 값이나 넣어준겁니다 ᄒ
p를 경유했는데 dp[i][p]dp[p][j]가 같은 값을 갖고 있다는 것은 dp[i][j]의 상태를 결정하기에 충분하기 때문입니도

yeahdy reacted with thumbs up emoji yeahdy reacted with eyes emoji
Copy link
Contributor

@yeongleej yeongleej Nov 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호 이거 진짜 똑똑한 생각인것 같아요!! 선후관계를 넣는 것!! 😮

jewan100 reacted with thumbs up emoji
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;
}
}
46 changes: 46 additions & 0 deletions BOJ/1000-5000번/JW_2096.java
View file Open in desktop
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;
}
}
126 changes: 126 additions & 0 deletions BOJ/1000-5000번/JW_2955.java
View file Open in desktop
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();
}
}
136 changes: 136 additions & 0 deletions CodeTree/2019-2020년/JW_회전하는_빙하.java
View file Open in desktop
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;
}
}

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