-
Notifications
You must be signed in to change notification settings - Fork 4
[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
[4주차] 백제완 #49
Changes from 8 commits
33dda88
7e8fb73
dc2152f
0d7b2c4
8f75148
8280e62
e1076b2
e987d06
0da6646
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,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개 이하로 지을 수 있는지 | ||
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; | ||
} | ||
} |
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)); | ||
} | ||
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. 그러게여..🐹 필요없는 연산입니다! |
||
} |
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); | ||
} | ||
|
||
// 빠른 입력 함수 | ||
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. 나중에 같이 입력함수 이야기해봐요! |
||
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,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; | ||
} | ||
} |
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; | ||
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. 저는 웅덩이가 있는 곳을 2차원 boolean 배열을 만들어서 저장해줬는데, 그냥 int형 배열에 모두 다 저장해줘도 됐군요,,,,👍 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. 최대한 하나의 배열에서 끝내려고 -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]); // 왼쪽에서 오는 경우 | ||
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. 최댓값으로 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오호.. 다들 휴게소 개수 짱 깔끔하게 구하셨군요..!!👍