Skip to content

[4주차] 백제완 #49

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
merged 9 commits into from
Oct 6, 2024
50 changes: 50 additions & 0 deletions BOJ/1000-10000번/JW_1477.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import java.util.Arrays;

public class Main {

static int n, m, l;
static int[] arr;

public static void main(String[] args) throws Exception {
n = read();
m = read();
l = read();
arr = new int[n + 1]; // 주유소의 위치를 입력 받을 변수
for (int i = 0; i < n; i++)
arr[i] = read();
arr[n] = l; // 마지막으로 고속도로의 끝 입력
Arrays.sort(arr); // 이분 탐색을 위한 정렬
int left = 1, right = l;
// 이분 탐색
while (left <= right) {
int mid = (left + right) / 2;
// 해당 값이 가능했다면 최소를 찾기 위해 범위를 줄여줌
if (isPossible(mid)) {
right = mid - 1;
} else
left = mid + 1;
}
// 휴게소가 없는 구간의 길이의 최댓값들 중 최솟값 반환
System.out.println(left);
}

// 해당 값으로 주유소를 지었을 때 m개 이하로 지을 수 있는지
Copy link
Contributor

Choose a reason for hiding this comment

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

오호.. 다들 휴게소 개수 짱 깔끔하게 구하셨군요..!!👍

private static boolean isPossible(int target) {
int cnt = 0;
int cur = 0; // 현재 위치, 초기값은 시작 지점인 0
for (int i = 0; i < n; i++) {
cnt += (arr[i] - cur - 1) / target; // 현재 위치에서 다음 위치까지 갈 때 필요한 휴게소의 개수
cur = arr[i]; // 현재 위치 갱신
}
return cnt <= m;
}

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;
}
}
69 changes: 69 additions & 0 deletions BOJ/1000-10000번/JW_4386.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Main {

// 별과 별 사이의 거리를 저장할 객체
static class Edge {
int to;
double distance;

Edge(int to, double distance) {
this.to = to;
this.distance = distance;
}
}

public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
double[][] stars = new double[n][2];
for (int i = 0; i < n; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
stars[i][0] = Double.parseDouble(st.nextToken());
stars[i][1] = Double.parseDouble(st.nextToken());
}
// 별들의 거리 정보를 저장할 리스트
ArrayList<ArrayList<Edge>> graph = new ArrayList<>();
for (int i = 0; i < n; i++)
graph.add(new ArrayList<>());
// 모든 별들 사이의 거리를 계산하여 리스트에 저장
for (int i = 0; i < n - 1; i++)
for (int j = i + 1; j < n; j++) {
double distance = calDistance(stars[i], stars[j]);
graph.get(i).add(new Edge(j, distance));
graph.get(j).add(new Edge(i, distance));
}
// mst를 계산하기 위해 방문 처리할 배열
boolean[] visited = new boolean[n];
// 간선들의 가중치를 오름차순으로 정렬
PriorityQueue<Edge> pq = new PriorityQueue<>((o1, o2) -> Double.compare(o1.distance, o2.distance));
pq.offer(new Edge(0, 0)); // 시작 점(아무 곳이나 설정)
double mstDistance = 0; // 모든 점을 최소로 이었을 때 거리의 합
// Prim algorithm
while (!pq.isEmpty()) {
Edge cur = pq.poll();
int u = cur.to;
// 방문한 배열은 스킵
if (visited[u])
continue;
visited[u] = true;
mstDistance += cur.distance; // 거리의 합에 더해줌
for (Edge next : graph.get(u)) {
int v = next.to; // 다음으로 이동할 별
// 방문하지 않았다면
if (!visited[v])
pq.offer(next); // 큐에 삽입
}
}
System.out.println(mstDistance);
}

// 별과 별 사이의 거리 계산
private static double calDistance(double[] A, double[] B) {
return Math.sqrt(Math.pow(B[0] - A[0], 2) + Math.pow(B[1] - A[1], 2));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

마지막에 절대값으로 반환한 이유가 있을까요?

Copy link
Contributor Author

@jewan100 jewan100 Oct 1, 2024

Choose a reason for hiding this comment

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

그러게여..🐹 필요없는 연산입니다!
수정했습니다 ㅎ 감사합니다

}
26 changes: 26 additions & 0 deletions BOJ/1000-10000번/JW_7570.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
public class Main {
public static void main(String[] args) throws Exception {
int n = read();
int[] arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = read();
int[] lis = new int[n + 1]; // 최장 (연속) 증가 수열의 길이를 저장할 배열
int len = 0; // 최대 길이를 저장할 변수
for (int i = 0; i < n; i++) {
int idx = arr[i];
lis[idx] = lis[idx - 1] + 1; // 자신보다 하나 작은 값이 가진 LIS 길이 +1
len = Math.max(len, lis[i]); // 최대 길이 갱신
}
System.out.println(n - len);
}

// 빠른 입력 함수
Copy link
Contributor

Choose a reason for hiding this comment

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

저는 왜 빠른 입력 함수만 쓰면 에러가 날까요?,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 요상합니다,,,,,,,,,,,,,,,,,,,,,,,,,ㅋㅎㅋㅎ,, ㅠㅠ !

Copy link
Contributor Author

Choose a reason for hiding this comment

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

나중에 같이 입력함수 이야기해봐요!

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;
}
}
108 changes: 108 additions & 0 deletions CodeTree/2017-2018년/JW_토스트 계란틀.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.StringTokenizer;

public class Main {

static int n, l, r;
static int[][] toast; // 계란의 양을 저장할 배열
static boolean[][] visited; // 분리 가능한 지를 확인할 배열

static int[] dy = { 1, 0, -1, 0 };
static int[] dx = { 0, 1, 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());
l = Integer.parseInt(st.nextToken());
r = Integer.parseInt(st.nextToken());
toast = new int[n][n];
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < n; j++)
toast[i][j] = Integer.parseInt(st.nextToken());
}
int time = 0; // 계란의 이동 시간
while (separate()) { // 분리가 가능한가?
time++; // 분리 했다면 계란의 이동 시간 증가
}
System.out.println(time);
}

// 순차적으로 계란틀이 분리가 가능한 지 확인하는 함수
private static boolean separate() {
visited = new boolean[n][n];
boolean flg = false; // 분리가 됐는 지를 알려줄 검출 Flag
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
if (visited[i][j]) // 이미 분리한(방문한) 계란 틀은 스킵
continue;
// 순차적으로 순회하기 때문에 진행 방향인 아래, 오른쪽만 확인
for (int k = 0; k < 2; k++) {
int ni = i + dy[k];
int nj = j + dx[k];
// 다음 좌표와 합칠 수 있는 지
if (isPossible(i, j, ni, nj)) {
flg = true; // 합칠 수 있었음
distribute(ni, nj); // BFS를 이용해서 합칠 수 있는 계란들 합치기
}
}
}
return flg; // 검출 Flag 반환
}

// 계란틀이 분리가 가능하다면 계란 합치기
// BFS 이용
private static void distribute(int sy, int sx) {
int cnt = 0, sum = 0;
// BFS
Deque<int[]> dq = new ArrayDeque<>();
ArrayList<int[]> info = new ArrayList<>(); // BFS를 진행한 좌표들 저장
dq.offer(new int[] { sy, sx });
visited[sy][sx] = true;
while (!dq.isEmpty()) {
int[] cur = dq.poll();
int y = cur[0], x = cur[1];
// 정보 저장
cnt++;
sum += toast[y][x];
info.add(new int[] { y, x });

for (int i = 0; i < 4; i++) {
int ny = cur[0] + dy[i];
int nx = cur[1] + dx[i];
// 다음 좌표도 합칠 수 있는 지
if (isPossible(y, x, ny, nx)) {
visited[ny][nx] = true; // 방문처리
dq.offer(new int[] { ny, nx });
}
}
}
int avg = sum / cnt;
// 방문했던 좌표들 값 재할당
for (int i = 0; i < info.size(); i++) {
int y = info.get(i)[0], x = info.get(i)[1];
toast[y][x] = avg;
}
}

// 분리가 가능한 지 확인하는 함수
private static boolean isPossible(int y, int x, int ny, int nx) {
// 방문하지 않았던 좌표들 중
if (isValid(ny, nx) && !visited[ny][nx]) {
// 차이가 l이상 r이하
int diff = Math.abs(toast[y][x] - toast[ny][nx]);
return l <= diff && diff <= r;
}
return false;
}

// 경계 체크
private static boolean isValid(int y, int x) {
return 0 <= y && y < n && 0 <= x && x < n;
}
}
19 changes: 19 additions & 0 deletions Programmers/Level3/JW_42898.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class Solution {
final int MOD = 1_000_000_007; // 나머지 연산
public int solution(int m, int n, int[][] puddles) {
int[][] board = new int[n + 1][m + 1];
// 웅덩이가 있는 위치 표시
for (int[] puddle : puddles)
board[puddle[1]][puddle[0]] = -1;
Copy link
Contributor

Choose a reason for hiding this comment

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

저는 웅덩이가 있는 곳을 2차원 boolean 배열을 만들어서 저장해줬는데, 그냥 int형 배열에 모두 다 저장해줘도 됐군요,,,,👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

최대한 하나의 배열에서 끝내려고 -1로 표기했더니 계산도 간단해지고 괜찮더라구요!

board[0][1] = 1; // 시작 위치의 위 혹은 왼쪽을 1로 초기화
for (int i = 1; i < n + 1; i++)
for (int j = 1; j < m + 1; j++)
// 현재 위치가 웅덩이가 아니라면
if (board[i][j] != -1) {
int up = Math.max(0, board[i - 1][j]); // 위쪽에서 오는 경우
int lf = Math.max(0, board[i][j - 1]); // 왼쪽에서 오는 경우
Copy link
Contributor

Choose a reason for hiding this comment

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

이렇게 최댓값으로 바로 받아와도 되는군요..!! 👍 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

최댓값으로 0과 함께 받아오면 체크해둔 -1을 무시할 수 있어요!

board[i][j] = (up + lf) % MOD; // 가능한 경우의 수 계산
}
return board[n][m];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
SELECT
C.ID,
C.GENOTYPE,
P.GENOTYPE PARENT_GENOTYPE
FROM
ECOLI_DATA C
INNER JOIN ECOLI_DATA P
ON C.PARENT_ID = P.ID
WHERE
C.GENOTYPE & P.GENOTYPE = P.GENOTYPE
ORDER BY
C.ID