Skip to content

[한종욱-14주차 알고리즘 스터디] #68

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

Open
wants to merge 80 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
858b242
Two Dots
Ukj0ng Feb 1, 2025
1bcacaf
크리보드
Ukj0ng Feb 1, 2025
e307eac
소년 점프
Ukj0ng Feb 1, 2025
ca5c5e4
마법사 상어와 비바라기
Ukj0ng Feb 1, 2025
b1fec0c
투에-모스 문자열
Ukj0ng Feb 1, 2025
e9840e2
당근 훔쳐 먹기
Ukj0ng Feb 2, 2025
11407f2
당근 훔쳐 먹기 주석 추가
Ukj0ng Feb 2, 2025
3e87c38
콘센트
Ukj0ng Feb 9, 2025
410215d
소코반
Ukj0ng Feb 9, 2025
cfa0f8e
점프 게임
Ukj0ng Feb 9, 2025
981b2f4
팀배분
Ukj0ng Feb 9, 2025
c4f2fd8
조 짜기(각 구간의 최대값, 최소값을 미리 구해놓는 방법)
Ukj0ng Feb 9, 2025
2e3013f
조 짜기(매번 최대값, 최소값 구하기)
Ukj0ng Feb 9, 2025
881d62c
LCS 2
Ukj0ng Feb 16, 2025
e3bf1c6
숫자 더하기
Ukj0ng Feb 16, 2025
4351201
과일 탕후루
Ukj0ng Feb 16, 2025
4460d4b
죽음의 비
Ukj0ng Feb 16, 2025
a56e377
출근 기록 DFS
Ukj0ng Feb 16, 2025
8041cbf
출근 기록 DP
Ukj0ng Feb 16, 2025
6bcc111
작은 벌점
Ukj0ng Feb 16, 2025
71e968c
1, 2, 3 더하기 2
Ukj0ng Feb 18, 2025
e58d012
직사각형 탈출
Ukj0ng Feb 18, 2025
f925917
과자 나눠주기
Ukj0ng Feb 23, 2025
beaa8e1
달력
Ukj0ng Feb 23, 2025
bb66ea6
DFS 스페셜 저지
Ukj0ng Feb 23, 2025
47de624
미세먼지 안녕
Ukj0ng Feb 23, 2025
f710321
줄세우기
Ukj0ng Mar 3, 2025
ec1f1fb
세 용액
Ukj0ng Mar 3, 2025
80e3da4
돌다리
Ukj0ng Mar 4, 2025
212d702
BOJ 거리
Ukj0ng Mar 5, 2025
72708a0
히오스 프로게이머
Ukj0ng Mar 5, 2025
e0daef1
레벨 햄버거
Ukj0ng Mar 6, 2025
47e3e42
서울 지하철 2호선
Ukj0ng Mar 6, 2025
1af6396
봄버맨
Ukj0ng Mar 9, 2025
64845a7
어른 상어
Ukj0ng Mar 9, 2025
d4f70c7
모래성
Ukj0ng Mar 9, 2025
f525644
나의 인생에는 수학과 함께
Ukj0ng Mar 9, 2025
fda3945
레벨 햄버거
Ukj0ng Mar 9, 2025
f1766ef
여왕벌
Ukj0ng Mar 10, 2025
de6ccf7
레벨 햄버거
Ukj0ng Mar 10, 2025
092a1c4
경쟁적 전염
Ukj0ng Mar 10, 2025
c2490ad
여왕벌
Ukj0ng Mar 12, 2025
b47a304
거울 설치
Ukj0ng Mar 12, 2025
cc43f57
트리
Ukj0ng Mar 12, 2025
5ee4d9b
회전 초밥
Ukj0ng Mar 12, 2025
715744d
소셜 네트워킹 어플리케이션
Ukj0ng Mar 16, 2025
c343032
문자열 지옥에 빠진 호석
Ukj0ng Mar 16, 2025
c1ca87c
문자열 지옥에 빠진 호석
Ukj0ng Mar 22, 2025
30a75d1
휴게소 세우기
Ukj0ng Mar 22, 2025
758ec58
진우의 달 여행(Large)
Ukj0ng Mar 22, 2025
ffd6916
게리맨더링 2
Ukj0ng Mar 22, 2025
0a26100
문자판
Ukj0ng Mar 22, 2025
1063827
진우의 달 여행(Large)
Ukj0ng Mar 22, 2025
72cd29f
친구 네트워크
Ukj0ng Mar 22, 2025
26be21c
선물 전달
Ukj0ng Mar 31, 2025
b529e63
택배 배송
Ukj0ng Mar 31, 2025
93e6cff
Count Circle Groups
Ukj0ng Mar 31, 2025
1290748
별자리 만들기
Ukj0ng Mar 31, 2025
291d11b
숫자카드
Ukj0ng Mar 31, 2025
0fd77c6
경로 찾기
Ukj0ng Apr 1, 2025
ab09f4a
컨베이어 벨트 위의 로봇
Ukj0ng Apr 1, 2025
6ce0aca
이중 우선순위 큐
Ukj0ng Apr 1, 2025
895ff91
도로검문
Ukj0ng Apr 1, 2025
09842b4
도로검문
Ukj0ng Apr 3, 2025
eb93999
복제 로봇
Ukj0ng Apr 3, 2025
2b70279
틱택토
Ukj0ng Apr 14, 2025
d04ed34
미친 로봇
Ukj0ng Apr 14, 2025
5ccf231
입국심사
Ukj0ng Apr 14, 2025
d98687e
입국심사
Ukj0ng Apr 14, 2025
a7bc315
호석이 두 마리 치킨
Ukj0ng Apr 14, 2025
cf419b4
마법사 상어와 복제
Ukj0ng Apr 15, 2025
a46dfba
달빛 여우
Ukj0ng Apr 17, 2025
a5f2800
놀이 공원
Ukj0ng Apr 20, 2025
7c39966
BFS 스페셜 저지
Ukj0ng Apr 20, 2025
d2cab13
통나무 자르기
Ukj0ng Apr 21, 2025
4f00290
팰린드롬 만들기
Ukj0ng Apr 21, 2025
c4f2e07
온풍기 안녕
Ukj0ng Apr 24, 2025
b3032f5
움직이는 미로 탈출
Ukj0ng Apr 24, 2025
aa8124b
싸지방에 간 준하
Ukj0ng Apr 24, 2025
075838f
일요일 아침의 데이트
Ukj0ng Apr 24, 2025
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
98 changes: 98 additions & 0 deletions 한종욱:10주차/boj10216.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import java.io.*;
import java.util.*;

public class boj10216 {
// 입출력을 위한 BufferedReader, BufferedWriter 선언
private static final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
private static final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
private static final StringBuilder sb = new StringBuilder();

// 분리집합(서로소 집합)의 루트 노드들을 저장하는 집합
private static Set<Integer> set;

// 유니온-파인드를 위한 배열 (x, y, r, parent)
private static int[][] uf;

// 각 집합의 크기를 저장하는 배열
private static int[] size;

// 적군 진영의 수
private static int n;

public static void main(String[] args) throws IOException {
int t = Integer.parseInt(br.readLine()); // 테스트 케이스 개수

for (int i = 0; i < t; i++) {
init(); // 초기 데이터 설정 및 연결 관계 계산
getDisjointSets(); // 분리된 집합의 수 계산
sb.append(set.size()).append("\n"); // 결과 저장
}

bw.write(sb.toString()); // 모든 결과 출력
bw.flush();
bw.close();
br.close();
}

// 초기 데이터를 설정하고 연결 관계를 계산하는 메소드
private static void init() throws IOException {
n = Integer.parseInt(br.readLine()); // 적군 진영의 수

// 배열 초기화
uf = new int[n][4]; // [x좌표, y좌표, 통신 반경, 부모 인덱스]
size = new int[n]; // 각 집합의 크기
set = new HashSet<>(); // 분리집합의 루트 노드 집합

// 각 진영 정보 입력 및 연결 관계 계산
for (int i = 0; i < n; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
uf[i][0] = Integer.parseInt(st.nextToken()); // x좌표
uf[i][1] = Integer.parseInt(st.nextToken()); // y좌표
uf[i][2] = Integer.parseInt(st.nextToken()); // 통신 반경
uf[i][3] = i; // 자기 자신을 부모로 초기화
size[i] = 1; // 초기 집합 크기는 1

// 이전에 입력받은 모든 진영과의 연결 여부 확인
for (int j = 0; j < i; j++) {
// 두 진영의 통신 반경 합의 제곱이 두 점 사이의 거리의 제곱보다 크거나 같으면 연결 가능
// (r1 + r2)^2 >= (x1 - x2)^2 + (y1 - y2)^2
if ((uf[i][2] + uf[j][2]) * (uf[i][2] + uf[j][2])
>= Math.abs(uf[i][0] - uf[j][0]) * Math.abs(uf[i][0] - uf[j][0])
+ Math.abs(uf[i][1] - uf[j][1]) * Math.abs(uf[i][1] - uf[j][1])) {
union(i, j); // 두 진영을 같은 집합으로 합침
}
}
}
}

// 두 집합을 합치는 메소드
private static void union(int x, int y) {
int X = find(x); // x의 루트 찾기
int Y = find(y); // y의 루트 찾기

if (X == Y) return; // 이미 같은 집합이면 종료

// 더 작은 집합을 더 큰 집합에 합침 (최적화)
if (size[X] < size[Y]) {
uf[X][3] = Y; // X의 부모를 Y로 설정
size[Y] += size[X]; // Y 집합의 크기 증가
} else {
uf[Y][3] = X; // Y의 부모를 X로 설정
size[X] += size[Y]; // X 집합의 크기 증가
}
}

// 요소의 루트를 찾는 메소드 (경로 압축 사용)
private static int find(int x) {
if (uf[x][3] == x) return x; // 자기 자신이 루트인 경우
return uf[x][3] = find(uf[x][3]); // 경로 압축
}

// 분리된 집합의 수를 계산하는 메소드
private static void getDisjointSets() {
for (int i = 0; i < n; i++) {
int root = find(i); // 각 요소의 루트 찾기
if (!set.contains(root)) set.add(root); // 새로운 루트면 집합에 추가
}
}
}
41 changes: 41 additions & 0 deletions 한종욱:10주차/boj1947.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import java.io.*;

public class boj1947 {
private static final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
private static final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
private static final int MOD = 1000000000; // 나머지 연산을 위한 모듈러 값
private static long[] dp; // 완전 순열의 경우의 수를 저장할 배열
private static int n; // 사람의 수

public static void main(String[] args) throws IOException {
init(); // 초기 설정 및 DP 계산
bw.write(String.valueOf(dp[n])); // 결과 출력
bw.flush();
bw.close();
br.close();
}

// 완전 순열(어느 누구도 자신의 선물을 받지 않는 순열)의 경우의 수 계산
private static void init() throws IOException {
n = Integer.parseInt(br.readLine()); // 사람 수 입력
dp = new long[n + 1]; // DP 배열 초기화

// 기본 케이스 설정
dp[0] = 1; // 0명일 때는 1가지 경우 (아무도 없는 경우)
dp[1] = 0; // 1명일 때는 0가지 경우 (자신의 선물을 받지 않을 방법 없음)

// 점화식을 이용한 DP 계산
// 완전 순열의 점화식: D(n) = (n-1) * (D(n-1) + D(n-2))
for (int i = 2; i <= n; i++) {
/*
* 이 점화식의 의미:
* 1. i번째 사람이 j번째 사람에게 선물을 줄 때(j != i)
* 2. 두 가지 경우가 발생:
* a. j번째 사람이 i번째 사람에게 선물을 줌 -> 나머지 n-2명에 대한 완전 순열 문제(dp[i-2])
* b. j번째 사람이 i번째 사람에게 선물을 주지 않음 -> i와 j를 제외한 나머지에 대한 완전 순열(dp[i-1])
* 3. 이를 j의 n-1가지 경우에 대해 모두 계산
*/
dp[i] = (i-1)*(dp[i-1] + dp[i-2]) % MOD; // 오버플로우 방지를 위한 모듈러 연산
}
}
}
57 changes: 57 additions & 0 deletions 한종욱:10주차/boj2591.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import java.io.*;

public class boj2591 {
// 입출력을 위한 BufferedReader, BufferedWriter 선언
private static final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
private static final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

// 동적 프로그래밍을 위한 배열
private static int[] dp; // dp[i]: i길이까지의 숫자를 해석하는 경우의 수

// 입력된 숫자 카드의 길이
private static int n;

public static void main(String[] args) throws IOException {
init(); // 초기 데이터 설정 및 DP 계산

// 결과 출력
bw.write(String.valueOf(dp[n]));
bw.flush();
bw.close();
br.close();
}

/**
* 초기 데이터를 설정하고 DP를 계산하는 메소드
* 1~34까지의 숫자로 해석하는 경우의 수를 계산합니다.
*/
private static void init() throws IOException {
String input = br.readLine(); // 숫자 카드 입력
n = input.length(); // 숫자 카드 길이
dp = new int[n + 1]; // DP 배열 초기화

// 기본 경우: 빈 문자열은 1가지 방법으로 해석 가능
dp[0] = 1;

// 각 위치까지의 해석 방법 수 계산
for (int i = 1; i <= n; i++) {
char current = input.charAt(i - 1); // 현재 숫자

// 한 자리 숫자로 해석하는 경우 (0이 아닐 때만 가능)
if (current != '0') {
dp[i] += dp[i - 1]; // 이전 위치까지의 해석 방법 수를 더함
}

// 두 자리 숫자로 해석하는 경우 (두 번째 자리부터 가능)
if (i > 1) {
char prev = input.charAt(i - 2); // 이전 숫자
int twoDigitNum = (prev - '0') * 10 + (current - '0'); // 두 자리 숫자 계산

// 두 자리 숫자가 10~34 범위이고 첫 자리가 0이 아닐 때
if (prev != '0' && twoDigitNum >= 10 && twoDigitNum <= 34) {
dp[i] += dp[i - 2]; // 두 자리 전까지의 해석 방법 수를 더함
}
}
}
}
}
119 changes: 119 additions & 0 deletions 한종욱:10주차/boj4386.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import java.io.*;
import java.util.*;

public class boj4386 {
// 입출력을 위한 BufferedReader, BufferedWriter 선언
private static final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
private static final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

// stars[i][0]: i번째 별의 x좌표, stars[i][1]: i번째 별의 y좌표
private static double[][] stars;

// 각 별까지의 최소 거리를 저장하는 배열
private static double[] dist;

// 방문 여부를 체크하는 배열
private static boolean[] visited;

// 별의 개수
private static int n;

public static void main(String[] args) throws IOException {
init(); // 초기 데이터 설정

// 프림 알고리즘으로 최소 신장 트리 구성
double answer = prim(0);

// 소수점 둘째 자리까지 출력 (반올림)
bw.write(String.valueOf(Math.round(answer*100)/100.0));
bw.flush();
bw.close();
br.close();
}

/**
* 초기 데이터를 설정하는 메소드
* 별의 개수와 좌표를 입력받아 초기화합니다.
*/
private static void init() throws IOException {
n = Integer.parseInt(br.readLine()); // 별의 개수 입력

// 배열 초기화
stars = new double[n][2]; // 별 좌표 배열
dist = new double[n]; // 최소 거리 배열
visited = new boolean[n]; // 방문 체크 배열

// 최소 거리를 매우 큰 값으로 초기화 (무한대 역할)
Arrays.fill(dist, 1e6);

// 각 별의 좌표 입력
for (int i = 0; i < n; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
double x = Double.parseDouble(st.nextToken());
double y = Double.parseDouble(st.nextToken());
stars[i][0] = x;
stars[i][1] = y;
}
}

/**
* 프림 알고리즘을 사용하여 최소 신장 트리를 구성하는 메소드
* @param start 시작 별의 인덱스
* @return 최소 신장 트리의 가중치 합 (최소 비용)
*/
private static double prim(int start) {
// 우선순위 큐를 사용하여 거리가 가장 짧은 별부터 선택
// [별 인덱스, 거리]를 저장
PriorityQueue<double[]> pq = new PriorityQueue<>((o1, o2) -> Double.compare(o1[1], o2[1]));

double sum = 0.0; // 최소 신장 트리의 총 가중치

dist[start] = 0.0; // 시작 별까지의 거리는 0
pq.add(new double[]{start, dist[start]}); // 시작 별을 큐에 추가

// 모든 별을 연결할 때까지 반복
while (!pq.isEmpty()) {
double[] current = pq.poll(); // 거리가 가장 짧은 별 선택
int currentStar = (int)current[0]; // 현재 별의 인덱스

// 이미 방문한 별이면 스킵
if (visited[currentStar]) continue;

// 현재 별 방문 처리 및 가중치 합산
visited[currentStar] = true;
sum += current[1]; // 현재까지의 거리를 합산

// 다른 모든 별과의 거리 계산
for (int i = 0; i < n; i++) {
// 자기 자신이거나 이미 방문한 별은 스킵
if (i == currentStar || visited[i]) continue;

// 현재 별에서 i번째 별까지의 거리 계산
double newDist = distance(
stars[currentStar][0], stars[currentStar][1],
stars[i][0], stars[i][1]
);

// 기존 거리보다 더 짧으면 업데이트
if (newDist < dist[i]) {
dist[i] = newDist;
pq.add(new double[]{i, dist[i]}); // 업데이트된 별을 큐에 추가
}
}
}

return sum; // 최소 신장 트리의 총 가중치 반환
}

/**
* 두 점 사이의 유클리드 거리를 계산하는 메소드
* @param x1 첫 번째 점의 x좌표
* @param y1 첫 번째 점의 y좌표
* @param x2 두 번째 점의 x좌표
* @param y2 두 번째 점의 y좌표
* @return 두 점 사이의 거리
*/
private static double distance(double x1, double y1, double x2, double y2) {
return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
}
Loading