├── .github └── ISSUE_TEMPLATE │ ├── -------------------------.md │ ├── -----------.md │ ├── --------.md │ └── take_my_idea.md ├── .gitignore ├── Bonus ├── Problem05A │ ├── Main.java │ ├── data │ │ └── solve.py │ ├── main.cpp │ └── main.rs ├── Problem05B │ ├── Main.java │ └── main.rs ├── Problem05C │ ├── Main.java │ └── main.rs ├── Problem05D │ ├── Main.java │ └── main.rs ├── Problem05E │ ├── Main.java │ └── main.rs ├── Problem05F │ ├── Main.java │ └── main.rs ├── Problem05G │ ├── Main.java │ └── main.rs ├── Problem05H │ └── Main.java ├── Problem05I │ └── Main.java ├── Problem05J │ ├── Main.java │ └── solution.cpp ├── Problem05K │ ├── Main.java │ └── solution.cpp ├── Problem05L │ └── Main.java ├── Problem05M │ └── Main.java ├── Problem05N │ └── Main.java ├── Problem05O │ ├── Main.java │ └── Solution.cpp └── Problem05P │ └── Main.java ├── LICENSE ├── Projects ├── DynamicArray │ └── Java │ │ ├── DynamicArray.java │ │ └── DynamicArrayTest.java └── Scanner │ └── Javascript │ └── Scanner.js ├── README.md ├── chapter01 ├── problem_a │ ├── Main.java │ ├── app.js │ ├── main.rs │ ├── readme.md │ ├── solution.cpp │ └── solution.py ├── problem_b │ ├── Main.java │ ├── app.js │ ├── main.rs │ ├── solution.cpp │ └── solution.py ├── problem_c │ ├── Main.java │ ├── app.js │ ├── main.rs │ ├── solution.cpp │ └── solution.py ├── problem_d │ ├── Main.java │ ├── app.js │ ├── main.rs │ ├── solution.cpp │ └── solution.py ├── problem_e │ ├── Main.java │ ├── app.js │ ├── main.rs │ ├── solution.cpp │ └── solution.py ├── problem_f │ ├── Main.java │ ├── app.js │ ├── main.rs │ └── solution.cpp ├── problem_g │ ├── Main.java │ ├── app.js │ ├── main.rs │ └── solution.cpp ├── problem_h │ ├── Main.java │ ├── app.js │ ├── main.rs │ └── solution.cpp ├── problem_i │ ├── Main.java │ ├── app.js │ ├── main.rs │ └── solution.cpp └── problem_j │ ├── Main.java │ ├── app.js │ ├── main.rs │ └── solution.cpp ├── chapter02 ├── problem_a │ ├── Main.java │ ├── main.rs │ ├── solution.cpp │ └── solution.py ├── problem_b │ ├── Main.java │ ├── main.rs │ ├── solution.cpp │ └── solution.py ├── problem_c │ ├── Main.java │ ├── main.rs │ ├── solution.cpp │ └── solution.py ├── problem_d │ ├── Main.java │ ├── main.rs │ └── solution.cpp ├── problem_e │ ├── Main.java │ ├── main.rs │ ├── solution.cpp │ └── solution.py ├── problem_f │ ├── Main.java │ ├── main.rs │ ├── solution.cpp │ └── solution.py ├── problem_g │ ├── Main.java │ ├── main.rs │ ├── solution.cpp │ └── solution.py ├── problem_h │ ├── Main.java │ ├── solution.cpp │ └── solution.py ├── problem_i │ ├── Main.java │ ├── main.rs │ ├── solution.cpp │ └── solution.py └── problem_j │ ├── Main.java │ ├── main.rs │ ├── solution.cpp │ └── solution.py ├── chapter03 ├── problem_a │ ├── Main.java │ ├── main.rs │ ├── solution.cpp │ ├── solution.js │ └── solution.py ├── problem_b │ ├── Main.java │ ├── main.rs │ ├── solution.cpp │ └── solution.py ├── problem_c │ ├── Main.java │ ├── main.rs │ ├── solution.cpp │ └── solution.py ├── problem_d │ ├── Main.java │ ├── main.rs │ ├── solution.cpp │ └── solution.py ├── problem_e │ ├── Main.java │ ├── solution.cpp │ └── solution.py ├── problem_f │ ├── Main.java │ ├── main.rs │ ├── solution.cpp │ └── solution.py ├── problem_g │ ├── Main.java │ ├── solution.cpp │ └── solution.py ├── problem_h │ ├── Main.java │ ├── main.rs │ └── solution.cpp ├── problem_i │ ├── Main.java │ ├── main.rs │ └── solution.cpp ├── problem_j │ ├── Main.java │ ├── main.rs │ └── solution.cpp └── problem_k │ ├── Main.java │ └── main.cpp ├── chapter04 ├── problem_a │ ├── Main.java │ ├── main.rs │ └── solution.cpp ├── problem_b │ ├── Main.java │ ├── main.rs │ └── solution.cpp ├── problem_c │ ├── Main.java │ ├── main.rs │ └── solution.cpp ├── problem_d │ ├── Main.java │ ├── main.rs │ └── solution.cpp ├── problem_e │ ├── Main.java │ ├── main.rs │ └── solution.cpp ├── problem_f │ ├── Main.java │ ├── main.rs │ └── solution.cpp ├── problem_g │ ├── Main.java │ ├── main.rs │ └── solution.cpp ├── problem_h │ ├── Main.java │ ├── main.rs │ └── solution.cpp ├── problem_i │ ├── Main.java │ ├── main.rs │ └── solution.cpp └── problem_j │ ├── Main.java │ ├── main.rs │ └── solution.cpp ├── chapter05 ├── problem_a │ ├── Main.java │ └── main.cpp ├── problem_b │ ├── Main.java │ └── main.cpp ├── problem_c │ ├── Main.java │ └── main.cpp ├── problem_d │ ├── Main.java │ └── solution.cpp ├── problem_e │ ├── Main.java │ └── main.cpp ├── problem_f │ ├── Main.java │ └── main.cpp ├── problem_g │ ├── Main.java │ └── main.cpp ├── problem_h │ ├── Main.java │ └── main.cpp ├── problem_i │ ├── Main.java │ └── main.cpp ├── problem_j │ ├── Main.java │ └── main.cpp ├── problem_k │ ├── Main.java │ ├── Source.py │ ├── data │ │ ├── gen.py │ │ ├── input.01.txt │ │ ├── input.02.txt │ │ ├── input.03.txt │ │ ├── input.04.txt │ │ ├── input.05.txt │ │ ├── input.06.txt │ │ ├── input.07.txt │ │ ├── input.08.txt │ │ ├── input.09.txt │ │ ├── input.10.txt │ │ ├── input.11.txt │ │ ├── input.12.txt │ │ ├── input.13.txt │ │ ├── input.14.txt │ │ ├── input.15.txt │ │ ├── input.16.txt │ │ ├── input.17.txt │ │ ├── input.18.txt │ │ ├── input.19.txt │ │ ├── input.20.txt │ │ ├── input.21.txt │ │ ├── input.22.txt │ │ ├── input.23.txt │ │ ├── input.24.txt │ │ ├── input.25.txt │ │ ├── input.26.txt │ │ ├── input.27.txt │ │ ├── input.28.txt │ │ ├── input.29.txt │ │ ├── input.30.txt │ │ ├── input.31.txt │ │ ├── input.32.txt │ │ ├── input.33.txt │ │ ├── input.34.txt │ │ ├── input.35.txt │ │ ├── input.36.txt │ │ ├── input.37.txt │ │ ├── input.38.txt │ │ ├── input.39.txt │ │ ├── input.40.txt │ │ ├── input.41.txt │ │ ├── input.42.txt │ │ ├── input.43.txt │ │ ├── input.44.txt │ │ ├── input.45.txt │ │ ├── input.46.txt │ │ ├── input.47.txt │ │ ├── input.48.txt │ │ ├── input.49.txt │ │ ├── input.50.txt │ │ ├── output.01.txt │ │ ├── output.02.txt │ │ ├── output.03.txt │ │ ├── output.04.txt │ │ ├── output.05.txt │ │ ├── output.06.txt │ │ ├── output.07.txt │ │ ├── output.08.txt │ │ ├── output.09.txt │ │ ├── output.10.txt │ │ ├── output.11.txt │ │ ├── output.12.txt │ │ ├── output.13.txt │ │ ├── output.14.txt │ │ ├── output.15.txt │ │ ├── output.16.txt │ │ ├── output.17.txt │ │ ├── output.18.txt │ │ ├── output.19.txt │ │ ├── output.20.txt │ │ ├── output.21.txt │ │ ├── output.22.txt │ │ ├── output.23.txt │ │ ├── output.24.txt │ │ ├── output.25.txt │ │ ├── output.26.txt │ │ ├── output.27.txt │ │ ├── output.28.txt │ │ ├── output.29.txt │ │ ├── output.30.txt │ │ ├── output.31.txt │ │ ├── output.32.txt │ │ ├── output.33.txt │ │ ├── output.34.txt │ │ ├── output.35.txt │ │ ├── output.36.txt │ │ ├── output.37.txt │ │ ├── output.38.txt │ │ ├── output.39.txt │ │ ├── output.40.txt │ │ ├── output.41.txt │ │ ├── output.42.txt │ │ ├── output.43.txt │ │ ├── output.44.txt │ │ ├── output.45.txt │ │ ├── output.46.txt │ │ ├── output.47.txt │ │ ├── output.48.txt │ │ ├── output.49.txt │ │ └── output.50.txt │ └── main.cpp ├── problem_l │ └── Main.java ├── problem_m │ ├── Main.java │ └── main.cpp ├── problem_n │ ├── Main.java │ └── main.cpp └── problem_o │ ├── Main.java │ └── main.cpp ├── chapter06 ├── problem_a │ └── Main.java ├── problem_b │ ├── Main.java │ └── main.cpp ├── problem_c │ └── Main.java ├── problem_d │ ├── Main.java │ └── main.cpp ├── problem_e │ └── Main.java ├── problem_f │ ├── Main.java │ └── main.cpp ├── problem_g │ ├── Main.java │ └── main.cpp ├── problem_h │ ├── Main.java │ └── main.cpp ├── problem_i │ ├── Main.java │ └── main.cpp └── problem_j │ └── Main.java ├── chapter07 ├── problem_a │ ├── Main.java │ └── main.cpp ├── problem_b │ ├── Main.java │ └── main.cpp ├── problem_c │ ├── Main.java │ └── main.cpp ├── problem_d │ ├── Main.java │ └── main.cpp ├── problem_e │ ├── Main.java │ └── main.cpp ├── problem_f │ ├── Main.java │ └── main.cpp ├── problem_g │ ├── Main.java │ └── main.cpp ├── problem_h │ ├── Main.java │ └── main.cpp ├── problem_i │ ├── Main.java │ └── main.cpp ├── problem_j │ └── Main.java └── problem_k │ └── Main.java ├── chapter08 ├── problem_a │ ├── Main.java │ └── main.cpp ├── problem_b │ ├── Main.java │ └── main.cpp ├── problem_c │ ├── Main.java │ └── main.cpp ├── problem_d │ ├── Main.java │ └── main.cpp ├── problem_e │ ├── Main.java │ └── main.cpp ├── problem_f │ └── Main.java ├── problem_g │ └── Main.java └── problem_h │ └── Main.java ├── chapter09 ├── problem_a │ ├── Main.java │ └── main.cpp ├── problem_b │ ├── Main.java │ └── main.cpp ├── problem_c │ ├── Main.java │ └── main.cpp ├── problem_d │ ├── Main.java │ └── main.cpp ├── problem_e │ ├── Main.java │ └── main.cpp ├── problem_f │ ├── Main.java │ └── main.cpp ├── problem_g │ ├── Main.java │ └── main.cpp ├── problem_h │ ├── Main.java │ └── main.cpp ├── problem_i │ ├── Main.java │ └── main.cpp ├── problem_j │ ├── Main.java │ └── main.cpp ├── problem_k │ ├── Main.java │ └── main.cpp └── problem_l │ ├── Main.java │ └── main.cpp ├── chapter10 ├── problem_a │ ├── Main.java │ └── main.cpp ├── problem_b │ ├── Main.java │ └── main.cpp ├── problem_c │ ├── Main.java │ └── main.cpp ├── problem_d │ ├── Main.java │ └── main.cpp ├── problem_e │ └── Main.java └── problem_f │ └── Main.java └── chapter11 ├── problem_a └── Main.java ├── problem_b └── Main.java └── problem_c └── Main.java /.github/ISSUE_TEMPLATE/-------------------------.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 뼈대 코드 및 주석 수정 요청 3 | about: 뼈대코드와 주석에 문제가 있다면 알려주세요 4 | 5 | --- 6 | 7 | **문제 번호** 8 | 어떤 문제의 답안이 문제가 있는지 알려주세요 9 | 10 | **오류 상세** 11 | 발생한 오류에 대해 상세히 알려주세요 12 | 1. 문제 번호 13 | 2. 수정해야할 것 같은 사항 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/-----------.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 답안 수정/추가 요청 3 | about: 문제에 대한 답안을 수정/추가하기를 바라신다면 작성해주세요 4 | 5 | --- 6 | 7 | **문제 번호 및 언어** 8 | 요청한 문제 및 언어에 대해 알려주세요 9 | 10 | **요청사항** 11 | 1. 답안 추가 요청 12 | 2. 오탈자 수정 요청 13 | 3. 버전 갱신 요청 14 | 4. 기타 요청 사항 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/--------.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 답안 오류 제보 3 | about: 모범 답안에 오류가 있는 경우 알려주세요 4 | 5 | --- 6 | 7 | **문제 번호** 8 | 어떤 문제의 답안이 문제가 있는지 알려주세요 9 | 10 | **오류 상세** 11 | 발생한 오류에 대해 상세히 알려주세요 12 | 1. 문제 번호 13 | 2. 오류 메시지 혹은 증상 14 | 3. 발생 이유 혹은 예상되는 원인 15 | 3. 수정해야할 것 같은 사항 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/take_my_idea.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 아이디어 제보 (문제, 컨텐츠, 등) 3 | about: 과목에 추가되었으면 하는 내용을 제보해주세요 4 | 5 | --- 6 | 7 | 8 | -------------------------------------------------------------------------------- /Bonus/Problem05A/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | public static final int EMPTY = 0; // 폐기물이 존재하지 않는 칸 10 | public static final int EXISTS = 1; // 폐기물이 존재하는 칸 11 | 12 | public static void testCase(int caseIndex) { 13 | int N = scanner.nextInt(); 14 | int K = scanner.nextInt(); 15 | 16 | // 각 칸의 정보를 입력받는다. 17 | int[][] wastes = new int[N][N]; 18 | for (int r = 0; r < N; r += 1) { 19 | for (int c = 0; c < N; c += 1) { 20 | // wastes[r][c] := (r행 c열)칸의 폐기물 존재 여부 21 | wastes[r][c] = scanner.nextInt(); 22 | } 23 | } 24 | 25 | int answer = Integer.MAX_VALUE; 26 | 27 | // K*K 크기의 영역이 존재할 수 있는 모든 지점을 탐색한다. 28 | // 왼쪽 위 모서리 칸을 (firstRow, firstCol)로 기준을 두고 탐색한다. 29 | for (int firstRow = 0; firstRow + K - 1 < N; firstRow += 1) { 30 | for (int firstCol = 0; firstCol + K - 1 < N; firstCol += 1) { 31 | 32 | int lastRow = firstRow + K - 1; 33 | int lastCol = firstCol + K - 1; 34 | 35 | // 해당 영역 내부에 존재하는 폐기물의 수를 계산한다 36 | int numberOfWastes = 0; 37 | 38 | for (int r = firstRow; r <= lastRow; r += 1) { 39 | for (int c = firstCol; c <= lastCol; c += 1) { 40 | if (wastes[r][c] == EXISTS) { 41 | numberOfWastes += 1; 42 | } 43 | } 44 | } 45 | 46 | // 최소값을 갱신한다. 47 | answer = Math.min(numberOfWastes, answer); 48 | } 49 | } 50 | 51 | System.out.println(answer); 52 | } 53 | 54 | public static void main(String[] args) throws Exception { 55 | int caseSize = scanner.nextInt(); 56 | 57 | for (int caseIndex = 1; caseIndex <= caseSize; caseIndex += 1) { 58 | testCase(caseIndex); 59 | } 60 | 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /Bonus/Problem05A/data/solve.py: -------------------------------------------------------------------------------- 1 | import random 2 | -------------------------------------------------------------------------------- /Bonus/Problem05A/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | using namespace std; 9 | 10 | 11 | int getTile(int** waste, int K, int row, int col) { 12 | int answer = 0; 13 | 14 | for (int i = row; i < row + K; ++i) { 15 | for (int j = col; j < col + K; ++j) { 16 | if (waste[i][j]) answer++; 17 | } 18 | } 19 | return answer; 20 | 21 | } 22 | int get_minimum_trashes(int** waste, int N, int K) { 23 | 24 | int answer = getTile(waste, K, 0, 0); 25 | for (int row = 0; row <= N - K; ++row) { 26 | for (int col = 0; col <= N - K; ++col) { 27 | answer = std::min(answer, getTile(waste, K, row, col)); 28 | } 29 | 30 | } 31 | 32 | return answer; 33 | } 34 | 35 | void test_case(int caseIndex) { 36 | int N, K; 37 | std::cin >> N >> K; 38 | 39 | int** wastes = new int* [N]; 40 | for (int r = 0; r < N; r += 1) { 41 | wastes[r] = new int[N]; 42 | for (int c = 0; c < N; c += 1) { 43 | std::cin >> wastes[r][c]; 44 | } 45 | } 46 | 47 | int answer = get_minimum_trashes(wastes, N, K); 48 | printf("%d\n", answer); 49 | 50 | for (int r = 0; r < N; r += 1) { 51 | delete[] wastes[r]; 52 | } 53 | delete[] wastes; 54 | } 55 | 56 | int main() { 57 | int caseSize; 58 | std::cin >> caseSize; 59 | 60 | for (int caseIndex = 0; caseIndex < caseSize; caseIndex += 1) { 61 | test_case(caseIndex); 62 | } 63 | return 0; 64 | } -------------------------------------------------------------------------------- /Bonus/Problem05A/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use std::cmp; 3 | 4 | fn stdinln_i32() -> i32 { 5 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 6 | let mut buffer = String::new(); 7 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 8 | buffer.trim().parse::().unwrap() 9 | } 10 | 11 | fn stdinln_vec_i32() -> Vec { 12 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 13 | let mut buffer = String::new(); 14 | std::io::stdin().read_line(&mut buffer).expect("Failed to read line"); 15 | let ret: Vec = buffer.split(" ") 16 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 17 | .collect(); 18 | ret 19 | } 20 | 21 | fn solve() -> usize { 22 | let mut space = Vec::new(); 23 | let case_info = stdinln_vec_i32(); 24 | let full_width = case_info[0] as usize; 25 | let toy_width = case_info[1] as usize; 26 | for i in 0..full_width { 27 | space.push(stdinln_vec_i32()); 28 | } 29 | 30 | let mut smallest: usize = toy_width * toy_width; 31 | for seek_y in 0..=full_width - toy_width { // 5-3=2 0,1 32 | for seek_x in 0..=full_width - toy_width{ 33 | let mut count: usize = 0; 34 | for y in seek_y..seek_y + toy_width { 35 | for x in seek_x..seek_x + toy_width { 36 | if space[y][x] != 0 { 37 | count += 1; 38 | } 39 | } 40 | } 41 | smallest = cmp::min(smallest, count); 42 | } 43 | } 44 | smallest 45 | } 46 | 47 | 48 | fn main() { 49 | let nr_case = stdinln_i32(); 50 | let mut answer_vec :Vec = Vec::new(); 51 | for i in 0..nr_case { 52 | answer_vec.push(solve()); 53 | } 54 | for ans in answer_vec.iter() { 55 | println!("{}", ans); 56 | } 57 | } -------------------------------------------------------------------------------- /Bonus/Problem05D/Main.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dongyi-kim/10weeks-codingtest/cbaa4da2d4a099b270816c28b3f2c88a37504a93/Bonus/Problem05D/Main.java -------------------------------------------------------------------------------- /Bonus/Problem05J/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const int MAX_SIZE = 100; 4 | 5 | void initTile(int tile[][MAX_SIZE + 2], int n) 6 | { 7 | for (int r = 0; r <= n + 1; r++) 8 | { 9 | tile[r][0] = tile[r][n + 1] = 1; 10 | } 11 | for (int c = 0; c <= n + 1; c++) 12 | { 13 | tile[0][c] = tile[n + 1][c] = 1; 14 | } 15 | 16 | for (int r = 1; r <= n; r++) 17 | { 18 | for (int c = 1; c <= n; c++) 19 | { 20 | tile[r][c] = 0; 21 | } 22 | } 23 | } 24 | 25 | int dr[4] = { -1, 1, 0, 0 }; 26 | int dc[4] = { 0, 0, -1, 1 }; 27 | 28 | void testCase(int caseIndex) 29 | { 30 | int n, k; 31 | int tile[MAX_SIZE + 2][MAX_SIZE + 2]; 32 | 33 | scanf("%d %d", &n, &k); 34 | 35 | initTile(tile, n); 36 | 37 | 38 | int nowR, nowC; 39 | scanf("%d %d", &nowR, &nowC); 40 | 41 | tile[nowR][nowC] = 1; 42 | 43 | bool turnOn = true; 44 | int steps = 1; 45 | for (int i = 0; i < k; i++) 46 | { 47 | int dir; 48 | int len; 49 | scanf("%d %d", &dir, &len); 50 | 51 | //이미 로봇이 동작을 정지했다면 다음 명령들은 그냥 스킵한다 52 | if (turnOn == false) 53 | { 54 | continue; 55 | } 56 | 57 | dir -= 1; 58 | 59 | for (int j = 0; j < len; j++) 60 | { 61 | int nextR = nowR + dr[dir]; 62 | int nextC = nowC + dc[dir]; 63 | 64 | if (nextR < 1 || nextC < 1 || nextR > n || nextC > n || tile[nextR][nextC] != 0) 65 | { 66 | turnOn = false; 67 | break; 68 | } 69 | else 70 | { 71 | steps += 1; 72 | nowR = nextR; 73 | nowC = nextC; 74 | tile[nowR][nowC] = 1; 75 | } 76 | } 77 | } 78 | 79 | printf("%d\n", steps); 80 | } 81 | 82 | int main() 83 | { 84 | int caseNum; 85 | scanf("%d", &caseNum); 86 | 87 | for (int caseIndex = 0; caseIndex < caseNum; caseIndex++) 88 | { 89 | testCase(caseIndex); 90 | } 91 | return 0; 92 | } -------------------------------------------------------------------------------- /Bonus/Problem05L/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | public static void main(String[] args) throws Exception { 10 | int N = scanner.nextInt(); 11 | Timestamp[] logs = new Timestamp[N + 2]; 12 | 13 | logs[0] = new Timestamp(-1, "00:00"); 14 | logs[N + 1] = new Timestamp(-1, "48:00"); 15 | for (int i = 1; i <= N; i += 1) { 16 | int teamIndex = scanner.nextInt(); 17 | String stringTimestamp = scanner.next(); 18 | logs[i] = new Timestamp(teamIndex, stringTimestamp); 19 | } 20 | 21 | int pointA = 0; 22 | int pointB = 0; 23 | long timeA = 0; 24 | long timeB = 0; 25 | 26 | for (int i = 1; i <= N+1; i += 1) { 27 | if (pointA > pointB) { 28 | timeA += logs[i - 1].getElapsedTimeTo(logs[i]); 29 | } else if (pointA < pointB) { 30 | timeB += logs[i - 1].getElapsedTimeTo(logs[i]); 31 | } 32 | 33 | if (logs[i].teamIndex == 1) { 34 | pointA += 1; 35 | } else if (logs[i].teamIndex == 2) { 36 | pointB += 1; 37 | } 38 | } 39 | 40 | System.out.printf("%02d:%02d\n", timeA / 60, timeA % 60); 41 | System.out.printf("%02d:%02d\n", timeB / 60, timeB % 60); 42 | } 43 | 44 | } 45 | 46 | class Timestamp { 47 | public final long timeInSeconds; 48 | public final int teamIndex; 49 | 50 | public Timestamp(int teamIndex, String stringTimestamp) { 51 | this.teamIndex = teamIndex; 52 | 53 | String[] splited = stringTimestamp.split(":"); 54 | int minutes = Integer.parseInt(splited[0]); 55 | int seconds = Integer.parseInt(splited[1]); 56 | this.timeInSeconds = minutes * 60 + seconds; 57 | } 58 | 59 | public Timestamp(int teamIndex, int minutes, int seconds) { 60 | this.teamIndex = teamIndex; 61 | this.timeInSeconds = minutes * 60 + seconds; 62 | } 63 | 64 | public long getElapsedTimeTo(Timestamp next) { 65 | long dt = Math.abs(next.timeInSeconds - this.timeInSeconds); 66 | return dt; 67 | } 68 | } -------------------------------------------------------------------------------- /Bonus/Problem05N/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | public static final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); 9 | 10 | public static void main(String[] args) throws Exception { 11 | String S = scanner.next(); 12 | String P = scanner.next(); 13 | 14 | ArrayList matchedIndexes = StringUtil.getMatchedIndexes(S, P); 15 | 16 | for (int i = 0; i < matchedIndexes.size(); i += 1) { 17 | int index = matchedIndexes.get(i); 18 | writer.write(String.valueOf(index)); 19 | writer.write("\n"); 20 | } 21 | 22 | writer.flush(); 23 | writer.close(); 24 | } 25 | 26 | } 27 | 28 | class StringUtil { 29 | 30 | /** 31 | * 문자열 S의 내부에서 패턴 P가 등장하는 모든 시작 인덱스를 반환하는 함수 32 | * 33 | * @param S 34 | * @param P 35 | * @return 36 | */ 37 | public static ArrayList getMatchedIndexes(String S, String P) { 38 | ArrayList matchedIndexes = new ArrayList<>(); 39 | 40 | int N = S.length(); // 문자열의 길이 41 | int M = P.length(); // 패턴의 길이 42 | 43 | for (int i = 0; i + M - 1 < N; i += 1) { 44 | // 문자열 S의 모든 글자이자 패턴의 검사를 시작할 시작 인덱스 i에 대하여 45 | 46 | // 모든 글자가 일치했는지 여부 47 | boolean matched = true; 48 | 49 | for (int j = 0; j < M; j += 1) { 50 | // S[i]에서부터 등장하는 패턴 P의 각 글자 P[j]에 대하여 51 | 52 | // 일치하지 않는 글자가 등장했다면, 일치 여부를 갱신하고 종료한다. 53 | if (S.charAt(i + j) != P.charAt(j)) { 54 | matched = false; 55 | break; 56 | } 57 | } 58 | 59 | if (matched) { 60 | matchedIndexes.add(i); 61 | } 62 | } 63 | 64 | return matchedIndexes; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Projects/DynamicArray/Java/DynamicArray.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | import java.lang.*; 4 | 5 | public class DynamicArray { 6 | public static final int INITIAL_CAPACITY = 16; 7 | 8 | private T[] array; // 내부 저장 공간 배열 9 | private int capacity; // 내부 저장 공간의 실제 크기를 나타내는 변수 10 | private int size; // 실제로 저장된 원소의 수를 나타내는 변수 11 | 12 | public DynamicArray() { 13 | this.array = (T[]) (new Object[INITIAL_CAPACITY]); 14 | this.capacity = INITIAL_CAPACITY; 15 | this.size = 0; 16 | } 17 | 18 | /** 19 | * @TODO 배열에 존재하는 원소들을 사용해 초기화하는 생성자 구현 20 | * 21 | * @param array 22 | */ 23 | public DynamicArray(T[] array) { 24 | 25 | } 26 | 27 | 28 | /** 29 | * @TODO 가장 뒤에 새로운 원소를 추가하는 메소드 구현 30 | * 31 | * @param element 32 | */ 33 | public void add(T element) { 34 | 35 | } 36 | 37 | /** 38 | * @TODO 특정 인덱스에 위차한 원소를 삭제하는 메소드 구현. 삭제 후 뒤의 원소들은 모두 앞으로 한 칸씩 당긴다. 39 | * 40 | * @param index 41 | */ 42 | public void remove(int index) { 43 | 44 | } 45 | 46 | /** 47 | * @TODO 특정 인덱스에 위치한 원소를 반환하는 메소드 구현 48 | * 49 | * @param index 50 | * @return 51 | */ 52 | public T get(int index) { 53 | return null; 54 | } 55 | 56 | /** 57 | * @TODO 특정 인덱스에 위치한 원소를 수정하는 메소드 구현 58 | * 59 | * @param index 60 | * @param value 61 | */ 62 | public void set(int index, T value) { 63 | 64 | } 65 | 66 | 67 | /** 68 | * @TODO 현재 저장된 원소의 수를 반환하는 메소드 구현 69 | * 70 | * @return 71 | */ 72 | public int size() { 73 | return -1; 74 | } 75 | 76 | } -------------------------------------------------------------------------------- /Projects/Scanner/Javascript/Scanner.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const input = (()=>{ 3 | //콘솔에서 입력할시에는 모든 입력 후 Ctrl+D 누르면 사용 가능 4 | //stdin = ["1 23 456","789 1011 121314"] 의 형식임 5 | const stdin = fs.readFileSync('/dev/stdin').toString().split('\n'); 6 | let ln=0; 7 | //stdin[ln++] (ln = 현재 내가 읽고있는 라인 넘버) 8 | return ()=>stdin[ln++]; 9 | })(); 10 | 11 | //console.log(input()) 의 결과 : "1 23 456" 12 | //배열로 바꾸고싶은 경우 : console.log(input().split("")) ["1","23","456"] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 10주완성 알고리즘 코딩테스트 힌트/답안집 2 | 3 | 구름EDU에서 연재 중인 [***10주완성 알고리즘 코딩테스트***](https://edu.goorm.io/lecture/554/10주-완성-알고리즘-코딩테스트) 과목의 문제별 모범 답안 코드집입니다. 4 | 각 문제에 대한 모범 답안 코드가 수록되어 있습니다. 기본적으로 C++, Java, Python3 세 가지 언어로 작성 된 코드를 공식적으로 제공하며, 자신이 다른 언어로 작성한 답안 코드를 Pull-Request로 공유하여 병합할 수 있습니다. 5 | 6 |
7 | 8 | ## 과목을 수강하는 방법 9 | 10 | ### 구름EDU 10주완성 알고리즘 코딩테스트 11 | - 프로그래밍 문제 해결을 위해 알아야 할 여러 지식과 테크닉을 소개합니다. 12 | - 언어별 필수 내장기능 사용법과 시험/대회에서의 팁을 소개합니다. 13 | - 문제들을 실시간으로 제출하고 채점받아볼 수 있습니다. 14 | - https://edu.goorm.io/lecture/554/10주-완성-알고리즘-코딩테스트 15 | 16 | ## 자신의 답안 코드 공유하기 17 | 공식적으로는 C++, Java, Python3로 작성한 답안 코드를 제공하고 있습니다. 만약 이외의 언어로 자신이 작성한 코드를 본 레파지토리에 공유하고 싶다면 Pull-Request를 이용해주세요. 단, 코드 공유시 아래의 사항들을 유의해주세요. 18 | 19 | - 가독성을 위하여 공식 답안 코드와 변수/함수/클래스 이름을 최대한 맞춰주세요. 20 | - 답안 코드의 코딩 컨벤션을 지켜주세요. 21 | - 이미 해당 언어로 작성된 답안이 있다면 새로 만들지 말고 해당 파일을 수정해주세요. 22 | - 문제의 지문이나 예제 데이터등을 포함하지 말아주세요. 23 | - 답안 코드는 하나의 파일로 작성되어야 합니다. 24 | -------------------------------------------------------------------------------- /chapter01/problem_a/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | public class Main { 6 | public static final Scanner scanner = new Scanner(System.in); 7 | 8 | /** 9 | * 두 정수 a와 b중 더 큰 값을 반환하는 함수 10 | * 11 | * @param a 12 | * @param b 13 | * @return a와 b중 더 큰 값 14 | */ 15 | public static int getMax(int a, int b) { 16 | if (a > b) { 17 | return a; 18 | } else { 19 | return b; 20 | } 21 | } 22 | 23 | public static void main(String[] args) throws Exception { 24 | int p = scanner.nextInt(); 25 | int q = scanner.nextInt(); 26 | 27 | int answer = getMax(p, q); 28 | 29 | System.out.println(answer); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /chapter01/problem_a/app.js: -------------------------------------------------------------------------------- 1 | function getMax(a, b) { 2 | if ( a >= b) 3 | return a; 4 | else 5 | return b; 6 | } 7 | 8 | const input = []; 9 | 10 | require('readline') 11 | .createInterface(process.stdin, {}) 12 | .on('line', function(line) { 13 | input.push(line.trim()); 14 | }) 15 | .on('close', function() { 16 | const values = input[0].split(" ").map(Number); 17 | const a = values[0]; 18 | const b = values[1]; 19 | console.log(getMax(a,b)); 20 | }); -------------------------------------------------------------------------------- /chapter01/problem_a/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn stdinln_i32() -> i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn stdinln_vec_i32() -> Vec { 11 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 12 | let mut buffer = String::new(); 13 | std::io::stdin().read_line(&mut buffer).expect("Failed to read line"); 14 | let ret: Vec = buffer.split(" ") 15 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 16 | .collect(); 17 | ret 18 | } 19 | 20 | fn main(){ 21 | let inputs = stdinln_vec_i32(); 22 | let result = if(inputs[0] > inputs[1]){ 23 | inputs[0] 24 | } else { 25 | inputs[1] 26 | }; 27 | println!("{}", result) 28 | } -------------------------------------------------------------------------------- /chapter01/problem_a/readme.md: -------------------------------------------------------------------------------- 1 | # 힌트 2 | 3 |
4 | 보기

5 | 6 | > a와 b의 대소관계에 따라서 케이스를 나누어 볼 수 있다 7 | 8 |

9 | 10 | # 해설 11 | 12 |
13 | 해설

14 | 15 | 1. a가 b보다 크다면 a를 반환한다 16 | 2. a가 b와 같다면 a나 b를 반환한다 17 | 3. a가 b보다 작다면 b를 반환한다 18 | 19 |

20 | 21 | # Tip 22 | 23 | 이 문제에선 설명을 위해 직접 구현하지만, 대부분의 언어는 자체적으로 최대값 함수를 제공한다. 24 | 문제풀 때 잘 활용하자 25 | 26 | - Java - `Math.max(a,b)` 27 | - C++ - `std::max(a, b)` 28 | - python - `max(a,b)` 29 | - javascript - `Math.max(a,b)` 30 | -------------------------------------------------------------------------------- /chapter01/problem_a/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | /** 7 | * 두 정수 a와 b중 더 큰 값을 반환하는 함수 8 | * 9 | * @param a 10 | * @param b 11 | * @return a와 b중 더 큰 값 12 | */ 13 | int getMax(int a, int b) { 14 | if (a > b) { 15 | return a; 16 | } else { 17 | return b; 18 | } 19 | } 20 | 21 | int main() { 22 | int p, q; 23 | 24 | scanf("%d %d", &p, &q); 25 | 26 | int answer = getMax(p, q); 27 | 28 | printf("%d\n", answer); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /chapter01/problem_a/solution.py: -------------------------------------------------------------------------------- 1 | def get_max(a, b): 2 | """ 3 | 두 정수 a와 b중 더 큰 값을 반환하는 함수 4 | 5 | :param a: 6 | :param b: 7 | :return: 8 | """ 9 | if a > b: 10 | return a 11 | else: 12 | return b 13 | 14 | 15 | if __name__ == "__main__": 16 | p, q = [int(word) for word in input().split()] 17 | 18 | answer = get_max(p, q) 19 | 20 | print(answer) 21 | -------------------------------------------------------------------------------- /chapter01/problem_b/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | /** 10 | * 정수 배열의 모든 원소의 합을 계산하는 함수 11 | * 12 | * @param data 13 | * @param n 14 | * @return data[0] ~ data[n-1]의 합 15 | */ 16 | public static int getSum(int[] data, int n) { 17 | int answer = 0; 18 | 19 | for (int i = 0; i < n; i++) { 20 | answer += data[i]; 21 | } 22 | 23 | return answer; 24 | } 25 | 26 | public static void main(String[] args) throws Exception { 27 | int n = scanner.nextInt(); 28 | int[] data = new int[n]; 29 | for (int i = 0; i < n; i++) { 30 | data[i] = scanner.nextInt(); 31 | } 32 | 33 | int answer = getSum(data, n); 34 | 35 | System.out.println(answer); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /chapter01/problem_b/app.js: -------------------------------------------------------------------------------- 1 | function get_sum(data, length) 2 | { 3 | var sum = 0; 4 | 5 | for (var i=0; i i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn stdinln_vec_i32() -> Vec { 11 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 12 | let mut buffer = String::new(); 13 | std::io::stdin().read_line(&mut buffer).expect("Failed to read line"); 14 | let ret: Vec = buffer.split(" ") 15 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 16 | .collect(); 17 | ret 18 | } 19 | 20 | fn sum_vec_i32(source: Vec, nr_items: usize) -> i32 { 21 | let mut ret: i32 = 0; 22 | // Vec에서 sum을 구하는 함수를 만들어주십시오. 23 | for i in 0..nr_items { 24 | ret += source[i]; 25 | } 26 | // ret에 저장한 합계를 return합니다. 27 | ret 28 | } 29 | 30 | fn main(){ 31 | let nr_cases = stdinln_i32() as usize; 32 | let inputs = stdinln_vec_i32(); 33 | // sum_vec_i32 를 완성해주세요! 34 | let result = sum_vec_i32(inputs, nr_cases); 35 | println!("{}", result); 36 | } -------------------------------------------------------------------------------- /chapter01/problem_b/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | /** 7 | * 정수 배열의 모든 원소의 합을 계산하는 함수 8 | * 9 | * @param data 10 | * @param n 11 | * @return data[0] ~ data[n-1]의 합 12 | */ 13 | int getSum(int data[], int n) { 14 | int answer = 0; 15 | 16 | for (int i = 0; i < n; i++) { 17 | answer += data[i]; 18 | } 19 | 20 | return answer; 21 | } 22 | 23 | int main() { 24 | int n; 25 | int *data; 26 | 27 | scanf("%d", &n); 28 | data = new int[n]; 29 | for (int i = 0; i < n; i++) { 30 | scanf("%d", &data[i]); 31 | } 32 | 33 | int answer = getSum(data, n); 34 | 35 | printf("%d\n", answer); 36 | delete[] data; 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /chapter01/problem_b/solution.py: -------------------------------------------------------------------------------- 1 | def get_sum(data, n): 2 | """ 3 | n개의 정수 data 배열에서 모든 정수의 합을 반환하는 함수 4 | 5 | :param data: 6 | :param n: 7 | :return: 8 | """ 9 | answer = 0 10 | 11 | for value in data: 12 | answer += value 13 | 14 | return answer 15 | 16 | 17 | if __name__ == "__main__": 18 | n = int(input()) 19 | 20 | data = [int(word) for word in input().split()] 21 | 22 | answer = get_sum(data, n) 23 | 24 | print(answer) 25 | -------------------------------------------------------------------------------- /chapter01/problem_c/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | /** 10 | * 배열의 최대값을 계산하는 함수. 11 | * 12 | * @param data 13 | * @param n 14 | * @return data[0] ~ data[n-1]중 최대값. 15 | */ 16 | public static int getMax(int[] data, int n) { 17 | int answer = data[0]; 18 | 19 | for (int i = 0; i < n; i++) { 20 | if (answer < data[i]) { 21 | answer = data[i]; 22 | } 23 | } 24 | 25 | //최종적으로 answer은 data[0] ~ data[n-1]중 최대값을 가져야 한다. 26 | return answer; 27 | } 28 | 29 | public static void main(String[] args) throws Exception { 30 | int n = scanner.nextInt(); 31 | int[] data = new int[n]; 32 | for (int i = 0; i < n; i++) { 33 | data[i] = scanner.nextInt(); 34 | } 35 | 36 | int answer = getMax(data, n); 37 | 38 | System.out.println(answer); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /chapter01/problem_c/app.js: -------------------------------------------------------------------------------- 1 | function getMax(array, length) { 2 | var max = 0; 3 | for (var i=0; i= max) 5 | max = array[i]; 6 | } 7 | return max; 8 | } 9 | 10 | const input = []; 11 | require('readline') 12 | .createInterface(process.stdin, {}) 13 | .on('line', function(line) { 14 | input.push(line.trim()); 15 | }) 16 | .on('close', function() { 17 | const length = parseInt(input[0]); 18 | const values = input[1].split(" ").map(Number); 19 | console.log(getMax(values, length)); 20 | }); -------------------------------------------------------------------------------- /chapter01/problem_c/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn stdinln_i32() -> i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn stdinln_vec_i32() -> Vec { 11 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 12 | let mut buffer = String::new(); 13 | std::io::stdin().read_line(&mut buffer).expect("Failed to read line"); 14 | let ret: Vec = buffer.split(" ") 15 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 16 | .collect(); 17 | ret 18 | } 19 | 20 | fn max_vec_i32(source: Vec) -> i32 { 21 | // Vec에서 Maximum을 구하는 함수 예시. 22 | let max = source.iter().max().unwrap(); 23 | *(max) 24 | } 25 | 26 | fn main(){ 27 | let nr_case = stdinln_i32(); 28 | let biggest = max_vec_i32(stdinln_vec_i32()); 29 | println!("{}", biggest); 30 | } -------------------------------------------------------------------------------- /chapter01/problem_c/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | /** 7 | * 배열의 최대값을 계산하는 함수. 8 | * 9 | * @param data 10 | * @param n 11 | * @return data[0] ~ data[n-1]중 최대값. 12 | */ 13 | int getMax(int data[], int n) { 14 | int answer = data[0]; 15 | 16 | for (int i = 0; i < n; i++) { 17 | if (answer < data[i]) { 18 | answer = data[i]; 19 | } 20 | } 21 | 22 | return answer; 23 | } 24 | 25 | int main() { 26 | int n; 27 | int *data; 28 | 29 | scanf("%d", &n); 30 | data = new int[n]; 31 | for (int i = 0; i < n; i++) { 32 | scanf("%d", &data[i]); 33 | } 34 | 35 | int answer = getMax(data, n); 36 | 37 | printf("%d\n", answer); 38 | delete[] data; 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /chapter01/problem_c/solution.py: -------------------------------------------------------------------------------- 1 | def get_max(data, n): 2 | """ 3 | n개의 정수 data 배열에서 가장 큰 값을 반환하는 함수 4 | 5 | :param data: 6 | :param n: 7 | :return: 8 | """ 9 | answer = data[0] 10 | 11 | for value in data: 12 | if answer < value: 13 | answer = value 14 | 15 | return answer 16 | 17 | 18 | if __name__ == "__main__": 19 | n = int(input()) 20 | 21 | data = [int(word) for word in input().split()] 22 | 23 | answer = get_max(data, n) 24 | 25 | print(answer) 26 | -------------------------------------------------------------------------------- /chapter01/problem_d/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | /** 10 | * @param data 각 사람들의 키를 저장한 배열 11 | * @param n 사람들의 수 12 | * @param m 미주의 키 13 | * @param s 지수의 키 14 | * @return 미주 혹은 지수와 키가 일치하는 사람의 수 15 | */ 16 | public static int getCount(int[] data, int n, int m, int s) { 17 | int count = 0; //확인해보아야 할 후보의 수 18 | for (int i = 0; i < n; i++) { 19 | if (data[i] == m || data[i] == s) { 20 | count += 1; 21 | } 22 | } 23 | return count; 24 | } 25 | 26 | public static void main(String[] args) throws Exception { 27 | int n = scanner.nextInt(); 28 | int m = scanner.nextInt(); 29 | int s = scanner.nextInt(); 30 | int[] data = new int[n]; 31 | for (int i = 0; i < n; i++) { 32 | data[i] = scanner.nextInt(); 33 | } 34 | 35 | int answer = getCount(data, n, m, s); 36 | 37 | System.out.println(answer); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /chapter01/problem_d/app.js: -------------------------------------------------------------------------------- 1 | const input = []; 2 | require('readline') 3 | .createInterface(process.stdin, {}) 4 | .on('line', function(line) { 5 | input.push(line.trim()); 6 | }) 7 | .on('close', function() { 8 | const values = input[0].split(" ").map(Number); 9 | const array = input[1].split(" ").map(Number); 10 | var count = 0; 11 | const n = values[0]; 12 | const m = values[1]; 13 | const s = values[2]; 14 | array.forEach(function(height) { 15 | if (height == m || height == s) 16 | count++; 17 | }); 18 | console.log(count); 19 | }); -------------------------------------------------------------------------------- /chapter01/problem_d/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn stdinln_i32() -> i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn stdinln_vec_i32() -> Vec { 11 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 12 | let mut buffer = String::new(); 13 | std::io::stdin().read_line(&mut buffer).expect("Failed to read line"); 14 | let ret: Vec = buffer.split(" ") 15 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 16 | .collect(); 17 | ret 18 | } 19 | 20 | fn main(){ 21 | // 이 문제는 match 로 풀수 있을거라고 생각 할 수 있다. 22 | // 하지만 rust에서는 state safe를 위해서 23 | // match에서 변수를 match케이스로 사용할 수 없다! 24 | // 주의하자! 25 | let case_flag = stdinln_vec_i32(); 26 | let person_data = stdinln_vec_i32(); 27 | // let N = case_flag[0]; 28 | let miju = case_flag[1]; 29 | let suji = case_flag[2]; 30 | let mut answer = 0; 31 | for person in person_data.into_iter() { 32 | if(person == miju){ 33 | answer += 1; 34 | }else if(person == suji){ 35 | answer += 1; 36 | } 37 | } 38 | println!("{}", answer); 39 | } -------------------------------------------------------------------------------- /chapter01/problem_d/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | /** 7 | * 8 | * @param data 각 사람들의 키를 저장한 배열 9 | * @param n 사람들의 수 10 | * @param m 미주의 키 11 | * @param s 지수의 키 12 | * @return 미주 혹은 지수와 키가 일치하는 사람의 수 13 | */ 14 | int getCount(int data[], int n, int m, int s) { 15 | int count = 0; //확인해보아야 할 후보의 수 16 | for (int i = 0; i < n; i++) { 17 | if (data[i] == m || data[i] == s) { 18 | count += 1; 19 | } 20 | } 21 | return count; 22 | } 23 | 24 | int main() { 25 | int n, m, s; 26 | int *data; 27 | 28 | scanf("%d %d %d", &n, &m, &s); 29 | data = new int[n]; 30 | for (int i = 0; i < n; i++) { 31 | scanf("%d", &data[i]); 32 | } 33 | 34 | int answer = getCount(data, n, m, s); 35 | 36 | printf("%d\n", answer); 37 | delete[] data; 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /chapter01/problem_d/solution.py: -------------------------------------------------------------------------------- 1 | def get_count(data, n, m, s): 2 | """ 3 | 4 | :param data: 각 사람들의 키를 저장한 배열 5 | :param n: 사람들의 수 6 | :param m: 미주의 키 7 | :param s: 지수의 키 8 | :return: 미주 혹은 지수와 키가 일치하는 사람의 수 9 | """ 10 | count = 0 11 | 12 | for value in data: 13 | if value == m or value == s: 14 | count += 1 15 | 16 | return count 17 | 18 | 19 | if __name__ == "__main__": 20 | n, m, s = [int(word) for word in input().split()] 21 | 22 | heights = [int(word) for word in input().split()] 23 | 24 | answer = get_count(heights, n, m, s) 25 | 26 | print(answer) 27 | -------------------------------------------------------------------------------- /chapter01/problem_e/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | /** 10 | * 동아리 멤버들의 탑승 가능 여부를 출력하는 함수 11 | * 12 | * @param data 각 멤버들의 몸무게 data[0] ~ data[n-1] 13 | * @param n 멤버들의 수 14 | * @param p 놀이기구 탑승 가능 체중 제한 15 | * @param q 놀이기구 최대 하중 16 | */ 17 | public static void solve(int[] data, int n, int p, int q) 18 | { 19 | int c = 0; //탑승 가능한 사람의 수 20 | int s = 0; //탑승 가능한 사람의 몸무게 총합 21 | 22 | for(int i = 0 ; i < n ; i++) 23 | { //모든 몸무게 data[i]에 대하여 24 | 25 | if( data[i] <= p ) 26 | { //탑승 가능한 사람의 몸무게 data[i]에 대하여 27 | c += 1; 28 | s += data[i]; 29 | } 30 | } 31 | 32 | System.out.printf("%d %d\n", c, s); 33 | if(s <= q) 34 | { 35 | System.out.println("YES"); 36 | }else{ 37 | System.out.println("NO"); 38 | } 39 | } 40 | 41 | 42 | public static void main(String[] args) 43 | { 44 | int n = scanner.nextInt(); 45 | int p = scanner.nextInt(); 46 | int q = scanner.nextInt(); 47 | int[] data = new int[n]; 48 | for(int i = 0 ; i < n ; i ++) 49 | { 50 | data[i] = scanner.nextInt(); 51 | } 52 | 53 | solve(data, n, p, q); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /chapter01/problem_e/app.js: -------------------------------------------------------------------------------- 1 | const input = []; 2 | require('readline') 3 | .createInterface(process.stdin, {}) 4 | .on('line', function(line) { 5 | input.push(line.trim()); 6 | }) 7 | .on('close', function() { 8 | var count = 0; //이 변수에 탑승할 수 있는 회원의 수를 저장한다 9 | var sum = 0; //이 변수에 탑승할 수 있는 회원의 몸무게의 합을 구한다 10 | var answer = "NO"; 11 | const values = input[0].split(" ").map(Number); 12 | const data = input[1].split(" ").map(Number); 13 | const n = values[0]; 14 | const p = values[1]; 15 | const q = values[2]; 16 | for (var i=0; i i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn stdinln_vec_i32() -> Vec { 11 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 12 | let mut buffer = String::new(); 13 | std::io::stdin().read_line(&mut buffer).expect("Failed to read line"); 14 | let ret: Vec = buffer.split(" ") 15 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 16 | .collect(); 17 | ret 18 | } 19 | 20 | fn sum_vec_i32_customized(source: Vec, nr_items: usize, max_each: i32, max_total: i32) { 21 | // 문제에 맞게 함수를 완성해주세요. 22 | let mut total = 0; 23 | let mut nr_match = 0; 24 | // for person in target.iter_to() <<- 를 써도 좋다. 25 | for i in 0..nr_items { 26 | if(source[i] <= max_each){ 27 | total += source[i]; 28 | nr_match += 1; 29 | } 30 | } 31 | 32 | println!("{} {}", nr_match, total); 33 | 34 | let result: bool = total<=max_total; 35 | 36 | match result { 37 | true => println!("YES"), 38 | false => println!("NO"), 39 | } 40 | } 41 | 42 | fn main(){ 43 | let case_spec = stdinln_vec_i32(); 44 | let nr_person = case_spec[0] as usize; 45 | let max_each = case_spec[1]; 46 | let max_total = case_spec[2]; 47 | let case_data = stdinln_vec_i32(); 48 | // sum_vec_i32_customized 를 완성해주세요! 49 | sum_vec_i32_customized(case_data, nr_person, max_each, max_total); 50 | } -------------------------------------------------------------------------------- /chapter01/problem_e/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | /** 7 | * 동아리 멤버들의 탑승 가능 여부를 출력하는 함수 8 | * 9 | * @param data 각 멤버들의 몸무게 data[0] ~ data[n-1] 10 | * @param n 멤버들의 수 11 | * @param p 놀이기구 탑승 가능 체중 제한 12 | * @param q 놀이기구 최대 하중 13 | */ 14 | void solve(int data[], int n, int p, int q) { 15 | int c = 0; //탑승 가능한 사람의 수 16 | int s = 0; //탑승 가능한 사람의 몸무게 총합 17 | 18 | for (int i = 0; i < n; i++) { //모든 몸무게 data[i]에 대하여 19 | 20 | if (data[i] <= p) { //탑승 가능한 사람의 몸무게 data[i]에 대하여 21 | c += 1; 22 | s += data[i]; 23 | } 24 | } 25 | 26 | printf("%d %d\n", c, s); 27 | if (s <= q) { 28 | printf("YES"); 29 | } else { 30 | printf("NO"); 31 | } 32 | } 33 | 34 | int main() { 35 | int n, p, q; 36 | int *data; 37 | 38 | scanf("%d %d %d", &n, &p, &q); 39 | data = new int[n]; 40 | for (int i = 0; i < n; i++) { 41 | scanf("%d", &data[i]); 42 | } 43 | 44 | solve(data, n, p, q); 45 | 46 | delete[] data; 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /chapter01/problem_e/solution.py: -------------------------------------------------------------------------------- 1 | def solve(data, n, p, q): 2 | """ 3 | 동아리 멤버들의 탑승 가능 여부를 출력하는 함수 4 | 5 | :param data: 각 멤버들의 몸무게 data[0] ~ data[n-1] 6 | :param n: 멤버들의 수 7 | :param p: 놀이기구 탑승 가능 체중 제한 8 | :param q: 놀이기구 최대 하중 9 | """ 10 | 11 | count = 0 12 | sum = 0 13 | 14 | for weight in data: 15 | if weight <= p: 16 | count += 1 17 | sum += weight 18 | 19 | print("%d %d" % (count, sum)) 20 | if sum <= q: 21 | print("YES") 22 | else: 23 | print("NO") 24 | 25 | 26 | if __name__ == "__main__": 27 | n, p, q = [int(word) for word in input().split()] 28 | 29 | weights = [int(word) for word in input().split()] 30 | 31 | solve(weights, n, p, q) 32 | -------------------------------------------------------------------------------- /chapter01/problem_f/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | /** 10 | * 배열에서 특정 원소의 위치를 찾는 함수 11 | * @param data 중복 없는 정수 배열 data[0] ~ data[n-1] 12 | * @param n 배열의 크기 n 13 | * @param m 배열에서 찾고자 하는 원소 14 | * @return 원소가 존재한다면 인덱스를, 존재하지 않으면 -1을 반환한다. 15 | */ 16 | public static int findIndex(int[] data, int n, int m) 17 | { 18 | int index = -1; 19 | 20 | for(int i = 0 ; i < n ; i ++) 21 | { 22 | if(data[i] == m) 23 | { 24 | index = i; 25 | } 26 | } 27 | 28 | return index; 29 | } 30 | 31 | public static void main(String[] args) 32 | { 33 | int n = scanner.nextInt(); 34 | int m = scanner.nextInt(); 35 | int[] data = new int[n]; 36 | for(int i = 0 ; i < n ; i ++) 37 | { 38 | data[i] = scanner.nextInt(); 39 | } 40 | 41 | int answer = findIndex(data, n, m); 42 | 43 | System.out.println(answer); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /chapter01/problem_f/app.js: -------------------------------------------------------------------------------- 1 | function find_value(value, data, length) 2 | { 3 | var index = -1; 4 | for (var i=0; i i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn stdinln_vec_i32() -> Vec { 11 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 12 | let mut buffer = String::new(); 13 | std::io::stdin().read_line(&mut buffer).expect("Failed to read line"); 14 | let ret: Vec = buffer.split(" ") 15 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 16 | .collect(); 17 | ret 18 | } 19 | 20 | fn find_vec_i32(source: Vec, nr_items: usize, target: i32) -> Result{ 21 | // Vec에서 우리가 원하는 target을 찾아서 Result로 Return 하도록 해봅시다! 22 | // https://doc.rust-lang.org/stable/rust-by-example/error/result/early_returns.html 23 | // https://doc.rust-lang.org/stable/std/result/enum.Result.html 24 | // 좀더 러스트하게 짜보기위해서 찾은경우와 못찾은 경우 -1를 return해줄 것이 아니라 25 | // Result으로 묶어서 보내는 것이 적합하다. 26 | let mut i: usize = 0; 27 | let mut catch: bool = false; 28 | loop { 29 | if source[i] == target { 30 | catch = true; 31 | break; 32 | } 33 | 34 | i += 1; 35 | if i>=nr_items { 36 | break; 37 | } 38 | 39 | } 40 | // 찾지 못한경우 Err(-1)으로 Return 해줍니다. (Result참고) 41 | if catch == true { 42 | Ok(i) 43 | }else{ 44 | Err(-1) 45 | } 46 | } 47 | 48 | fn main(){ 49 | let case_spec = stdinln_vec_i32(); 50 | let inputs = stdinln_vec_i32(); 51 | let nr_case = case_spec[0] as usize; 52 | let look_for = case_spec[1]; 53 | 54 | // find_vec_i32 를 완성해주세요! 55 | let result = find_vec_i32(inputs, nr_case, look_for); 56 | match result { 57 | Ok(found) => println!("{}", found), 58 | Err(err_code) => println!("{}", err_code), 59 | } 60 | 61 | } -------------------------------------------------------------------------------- /chapter01/problem_f/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | /** 7 | * 배열에서 특정 원소의 위치를 찾는 함수 8 | * @param data 중복 없는 정수 배열 data[0] ~ data[n-1] 9 | * @param n 배열의 크기 n 10 | * @param m 배열에서 찾고자 하는 원소 11 | * @return 원소가 존재한다면 인덱스를, 존재하지 않으면 -1을 반환한다. 12 | */ 13 | int findIndex(int data[], int n, int m) { 14 | int index = -1; 15 | 16 | for (int i = 0; i < n; i++) { 17 | if (data[i] == m) { 18 | index = i; 19 | } 20 | } 21 | 22 | return index; 23 | } 24 | 25 | int main() { 26 | int n, m; 27 | int *data; 28 | 29 | scanf("%d %d", &n, &m); 30 | data = new int[n]; 31 | for (int i = 0; i < n; i++) { 32 | scanf("%d", &data[i]); 33 | } 34 | 35 | int answer = findIndex(data, n, m); 36 | 37 | printf("%d\n", answer); 38 | delete[] data; 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /chapter01/problem_g/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | /** 10 | * 배열에서 소속이 "AJOU"인 첫 원소와 마지막 원소를 출력하는 함수 11 | * @param school 각 사람들의 소속학교 정보 배열 12 | * @param n 사람들의 수 13 | */ 14 | public static void printIndexes(String[] school, int n) 15 | { 16 | int first = -1; //존재하지 않으면 -1 17 | int last = -1; //존재하지 않으면 -1 18 | 19 | for(int i = 0 ; i < n ; i++) 20 | { // 모든 소속 school[i]에 대해 차례로 21 | 22 | if( school[i].equals("AJOU") ) 23 | { // 소속이 "AJOU"인 사람의 번호 i에 대해 24 | 25 | if(first == -1) 26 | { // [0, i-1]에서 소속이 "AJOU"인 사람이 등장한 적 없던 경우 27 | // 이번이 첫 등장이다 28 | first = i + 1; 29 | } 30 | 31 | // 소속이 "AJOU"인 사람이 등장한 경우 덮어쓴다 32 | // 이번이 마지막 등장이다 33 | last = i + 1; 34 | } 35 | } 36 | 37 | System.out.printf("%d %d\n", first, last ); 38 | } 39 | 40 | public static void main(String[] args) 41 | { 42 | int n = scanner.nextInt(); 43 | String[] schools = new String[n]; 44 | for(int i = 0 ; i < n ; i++) 45 | { 46 | schools[i] = scanner.next(); 47 | } 48 | 49 | printIndexes(schools, n); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /chapter01/problem_g/app.js: -------------------------------------------------------------------------------- 1 | const input = []; 2 | require('readline') 3 | .createInterface(process.stdin, {}) 4 | .on('line', function(line) { 5 | input.push(line.trim()); 6 | }) 7 | .on('close', function() { 8 | const n = parseInt(input[0]); 9 | var first_ajou = -1; 10 | var last_ajou = -1; 11 | for (var i=1; i i32 { 9 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 10 | let mut buffer = String::new(); 11 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 12 | buffer.trim().parse::().unwrap() 13 | } 14 | 15 | fn stdinln_vec_multiple_str(nr_lines: usize) -> Vec { 16 | // 이 함수는 nr_lines의 라인 만큼 stdin으로 받아 nr_lines갯수의 String을 vector로 리턴합니다. 17 | let mut ret: Vec = Vec::new(); 18 | for _i in 0..nr_lines { 19 | ret.push(String::new()); 20 | std::io::stdin().read_line(&mut ret[_i]).expect("Failed to read line"); 21 | ret[_i] = ret[_i].trim().to_string(); 22 | } 23 | ret 24 | } 25 | 26 | fn get_ajou(source: Vec, nr_items: usize) -> CandidateAjou{ 27 | let mut ret = CandidateAjou{first:0, last:0}; 28 | let target= String::from("AJOU"); 29 | for i in 0..nr_items { 30 | if source[i].eq(&target) { 31 | ret.first = i+1; 32 | break; 33 | } 34 | } 35 | for i in (0..nr_items).rev() { 36 | if source[i].eq(&target) { 37 | ret.last = i+1; 38 | break; 39 | } 40 | } 41 | ret 42 | } 43 | 44 | fn main(){ 45 | let nr_case = stdinln_i32() as usize; 46 | let inputs = stdinln_vec_multiple_str(nr_case); 47 | let result = get_ajou(inputs, nr_case); 48 | println!("{} {}", result.first, result.last); 49 | 50 | } -------------------------------------------------------------------------------- /chapter01/problem_g/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | /** 8 | * 배열에서 소속이 "AJOU"인 첫 원소와 마지막 원소를 출력하는 함수 9 | * @param school 각 사람들의 소속학교 정보 배열 10 | * @param n 사람들의 수 11 | */ 12 | void printIndexes(string school[], int n) { 13 | int first = -1; //존재하지 않으면 -1 14 | int last = -1; //존재하지 않으면 -1 15 | 16 | for (int i = 0; i < n; i++) { 17 | if (school[i] == "AJOU") { 18 | if (first == -1) { 19 | first = i + 1; 20 | } 21 | 22 | last = i + 1; 23 | } 24 | } 25 | 26 | printf("%d %d\n", first, last); 27 | } 28 | 29 | int main() { 30 | int n; 31 | char buff[11]; 32 | string *school; 33 | 34 | scanf("%d", &n); 35 | school = new string[n]; 36 | 37 | for (int i = 0; i < n; i++) { 38 | scanf("%s", buff); 39 | school[i] = buff; 40 | } 41 | 42 | printIndexes(school, n); 43 | 44 | delete[] school; 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /chapter01/problem_h/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | 10 | /** 11 | * 평균과의 차가 가장 작은 데이터의 번호를 반환하는 함수 12 | * 여러 가지라면 가장 빠른 번호를 반환한다. 13 | * 14 | * @param data 15 | * @param n 16 | * @return int 가장 평균과 가까운 데이터의 번호 (1번부터 시작) 17 | */ 18 | public static int findIndex(int[] data, int n) 19 | { 20 | int x = 0; //존재하지 않는 경우는 없으므로, 일단 0이라고 가정 21 | int S = 0; //모든 데이터의 합 22 | 23 | for(int i = 0 ; i < n ; i++) 24 | { 25 | S += data[i]; 26 | } 27 | 28 | for(int i = 0 ; i < n ; i ++) 29 | { 30 | int dx = Math.abs(n * data[x] - S); //i까지의 원소들 중 평균과의 최소거리 31 | int di = Math.abs(n * data[i] - S); //현재 원소와 평균과의 거리 32 | if( di < dx ) 33 | { 34 | x = i; 35 | } 36 | } 37 | 38 | return x + 1; //실제 번호는 1부터 시작하므로 증가 39 | } 40 | 41 | public static void main(String[] args) 42 | { 43 | int n = scanner.nextInt(); 44 | int[] data = new int[n]; 45 | for(int i = 0 ; i < n ; i++) 46 | { 47 | data[i] = scanner.nextInt(); 48 | } 49 | 50 | int answer = findIndex(data, n); 51 | int index = answer - 1; 52 | 53 | System.out.printf("%d %d\n", answer, data[index]); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /chapter01/problem_h/app.js: -------------------------------------------------------------------------------- 1 | function find_value(value, data, length) 2 | { 3 | var index = -1; 4 | for (var i=0; i 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | /** 9 | * 평균과의 차가 가장 작은 데이터의 번호를 반환하는 함수 10 | * 여러 가지라면 가장 빠른 번호를 반환한다. 11 | * 12 | * @param data 13 | * @param n 14 | * @return int 가장 평균과 가까운 데이터의 번호 (1번부터 시작) 15 | */ 16 | int findIndex(int data[], int n) { 17 | int x = 0; //존재하지 않는 경우는 없으므로, 일단 0이라고 가정 18 | int S = 0; //모든 데이터의 합 19 | 20 | for (int i = 0; i < n; i++) { 21 | S += data[i]; 22 | } 23 | 24 | for (int i = 0; i < n; i++) { 25 | int dx = abs(n * data[x] - S); //i까지의 원소들 중 평균과의 최소거리 26 | int di = abs(n * data[i] - S); //현재 원소와 평균과의 거리 27 | if (di < dx) { 28 | x = i; 29 | } 30 | } 31 | 32 | return x + 1; //실제 번호는 1부터 시작하므로 증가 33 | } 34 | 35 | int main() { 36 | int n; 37 | int *data; 38 | 39 | scanf("%d", &n); 40 | data = new int[n]; 41 | 42 | for (int i = 0; i < n; i++) { 43 | scanf("%d", &data[i]); 44 | } 45 | 46 | int answer = findIndex(data, n); 47 | printf("%d %d\n", answer, data[answer-1]); 48 | 49 | delete[] data; 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /chapter01/problem_i/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | /** 10 | * 주어진 범위의 최소값의 위치를 반환하는 함수 11 | * @param data 데이터 배열 12 | * @param n 배열의 크기 13 | * @param begin 탐색 할 가장 첫(왼쪽) 인덱스 14 | * @param end 탐색 할 가장 마지막(오른쪽) 인덱스 15 | * @return data[begin] ~ data[end] 중 가장 작은 원소의 인덱스 16 | */ 17 | public static int getMinIndexInRange(int[] data, int n, int begin, int end) 18 | { 19 | int index = begin; //일단 data[begin]이 가장 작다고 가정 20 | 21 | for(int i = begin ; i <= end ; i++) 22 | { 23 | if(data[index] > data[i] ) 24 | { 25 | index = i; 26 | } 27 | } 28 | 29 | return index; 30 | } 31 | 32 | public static void selectionSort(int[] data, int n) 33 | { 34 | for(int i = 0 ; i < n ; i++) 35 | { 36 | //주어진 범위에서 가장 작은 원소의 위치를 찾는다. 37 | int minIndex = getMinIndexInRange( data, n, i, n-1 ); 38 | 39 | //두 숫자의 위치를 바꾼다. 40 | int temp = data[minIndex]; 41 | data[minIndex] = data[i]; 42 | data[i] = temp; 43 | } 44 | } 45 | 46 | public static void main(String[] args) throws Exception { 47 | int n = scanner.nextInt(); 48 | int[] data = new int[n]; 49 | for(int i = 0 ; i < n ; i++) 50 | { 51 | data[i] = scanner.nextInt(); 52 | } 53 | 54 | selectionSort(data, n); 55 | 56 | for(int i = 0; i < n ; i ++) 57 | { 58 | if( i > 0 ) 59 | { 60 | System.out.print(" "); 61 | } 62 | System.out.print(data[i]); 63 | } 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /chapter01/problem_i/app.js: -------------------------------------------------------------------------------- 1 | function selection_sort(data, length) 2 | { 3 | for(var i = 0 ; i < data.length ; i++ ) 4 | { 5 | for (var j = i+1 ; j < data.length ; j++ ) 6 | { 7 | if ( data[i] > data[j] ) { 8 | var temp = data[i]; 9 | data[i] = data[j]; 10 | data[j] = temp; 11 | } 12 | } 13 | } 14 | } 15 | 16 | const input = []; 17 | require('readline') 18 | .createInterface(process.stdin, {}) 19 | .on('line', function(line) { 20 | input.push(line.trim()); 21 | }) 22 | .on('close', function() { 23 | const n = parseInt(input[0]); 24 | const data = input[1].split(" ").map(Number); 25 | var answer = ""; 26 | 27 | selection_sort(data, n); 28 | 29 | for (var i=0; i i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn stdinln_vec_i32() -> Vec { 11 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 12 | let mut buffer = String::new(); 13 | std::io::stdin().read_line(&mut buffer).expect("Failed to read line"); 14 | let ret: Vec = buffer.split(" ") 15 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 16 | .collect(); 17 | ret 18 | } 19 | 20 | /* 21 | 이 문제도 저번문제와 같이 Method 스타일로 풀어봅시다.! 22 | 참고하면 좋은 문서 23 | https://doc.rust-lang.org/rust-by-example/fn/methods.html 24 | https://rinthel.github.io/rust-lang-book-ko/ch04-02-references-and-borrowing.html 25 | */ 26 | pub struct I32Sort { 27 | len : usize, 28 | data: Vec, 29 | } 30 | 31 | impl I32Sort { 32 | fn new(length: usize) -> I32Sort { 33 | I32Sort{len:length, data:Vec::new()} 34 | } 35 | 36 | fn get_from_stdinln(&mut self) { 37 | self.data = stdinln_vec_i32(); 38 | // 사전에 입력받은 길이 값과 실제 벡터 값이 다르면 ASSERT!한다. 39 | assert_eq!(self.data.len(), self.len); 40 | } 41 | 42 | fn sel_sort(&mut self){ 43 | // 여기서 선택정렬을 구현해주세요! 44 | for i in 0..self.len { 45 | let mut small = i; 46 | for j in i+1..self.len { 47 | if self.data[j] < self.data[small] { 48 | small = j; 49 | } 50 | } 51 | let temp = self.data[small]; 52 | self.data[small] = self.data[i]; 53 | self.data[i] = temp; 54 | } 55 | } 56 | 57 | fn print(self) { 58 | for num in self.data { 59 | print!("{} ", num); 60 | } 61 | println!(""); 62 | } 63 | } 64 | 65 | fn main(){ 66 | let nr_element = stdinln_i32() as usize; 67 | let mut problem = I32Sort::new(nr_element); 68 | problem.get_from_stdinln(); 69 | // I32Sort::sel_sort() 를 완성해주세요! 70 | problem.sel_sort(); 71 | problem.print(); 72 | } -------------------------------------------------------------------------------- /chapter01/problem_i/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | 7 | /** 8 | * 주어진 범위의 최소값의 위치를 반환하는 함수 9 | * @param data 데이터 배열 10 | * @param n 배열의 크기 11 | * @param begin 탐색 할 가장 첫(왼쪽) 인덱스 12 | * @param end 탐색 할 가장 마지막(오른쪽) 인덱스 13 | * @return data[begin] ~ data[end] 중 가장 작은 원소의 인덱스 14 | */ 15 | int getMinIndexInRange(int data[], int n, int begin, int end) { 16 | int index = begin; //일반 data[begin]이 가장 작다고 가정 17 | 18 | for (int i = begin; i <= end; i++) { 19 | if (data[index] > data[i]) { 20 | index = i; 21 | } 22 | } 23 | 24 | return index; 25 | } 26 | 27 | void selectionSort(int data[], int n) { 28 | for (int i = 0; i < n; i++) { 29 | //주어진 범위에서 가장 작은 원소의 위치를 찾는다. 30 | int minIndex = getMinIndexInRange(data, n, i, n - 1); 31 | 32 | //두 숫자의 위치를 바꾼다. 33 | int temp = data[minIndex]; 34 | data[minIndex] = data[i]; 35 | data[i] = temp; 36 | } 37 | } 38 | 39 | int main() { 40 | int n; 41 | int *data; 42 | 43 | scanf("%d", &n); 44 | data = new int[n]; 45 | 46 | for (int i = 0; i < n; i++) { 47 | scanf("%d", &data[i]); 48 | } 49 | 50 | selectionSort(data, n); 51 | 52 | for (int i = 0; i < n; i++) { 53 | if (i > 0) { 54 | printf(" "); 55 | } 56 | printf("%d", data[i]); 57 | } 58 | 59 | delete[] data; 60 | return 0; 61 | } -------------------------------------------------------------------------------- /chapter01/problem_j/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | /** 10 | * 1부터 i까지의 자연수의 합을 계산하는 함수 11 | * @param i 12 | * @return 13 | */ 14 | public static int getRangeSumFromOne(int i) { 15 | int sum = 0; 16 | 17 | for(int j = 1; j <= i ; j+= 1) 18 | { 19 | sum += j; 20 | } 21 | 22 | return sum; 23 | } 24 | 25 | 26 | public static long getAnswer(int N) 27 | { 28 | long answer = 0; 29 | for(int i = 1; i <= N; i++) 30 | { 31 | int rangeSum = getRangeSumFromOne(i); 32 | answer += rangeSum; 33 | } 34 | 35 | return answer; 36 | } 37 | 38 | 39 | public static void main(String[] args) throws Exception { 40 | int n = scanner.nextInt(); 41 | 42 | long answer = getAnswer(n); 43 | 44 | System.out.println(answer); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /chapter01/problem_j/app.js: -------------------------------------------------------------------------------- 1 | const input = []; 2 | require('readline') 3 | .createInterface(process.stdin, {}) 4 | .on('line', function(line) { 5 | input.push(line.trim()); 6 | }) 7 | .on('close', function() { 8 | const n = parseInt(input[0]); 9 | const sum = [0]; 10 | var answer = 0; 11 | for (var i=1; i<=n; i++) 12 | { 13 | sum[i] = sum[i-1] + i; 14 | } 15 | for (var i=1; i<=n; i++) 16 | { 17 | answer += sum[i]; 18 | } 19 | console.log(answer); 20 | }); -------------------------------------------------------------------------------- /chapter01/problem_j/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn stdinln_i32() -> i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | pub struct SumAndSum { 11 | seed: i32, 12 | result: Option, 13 | } 14 | 15 | impl SumAndSum { 16 | fn new(_seed: i32) -> SumAndSum { 17 | SumAndSum{seed:_seed, result:None} 18 | } 19 | 20 | fn calc(&mut self){ 21 | // 여기서 문제를 풀어주세요! 22 | let mut sum = 0; 23 | // 그룸IDE 구버젼 rustc 사용으로 인해 ..=self.seed 사용못함. 24 | for i in 1..self.seed + 1{ 25 | for j in 1..i+1{ 26 | sum += j; 27 | } 28 | } 29 | self.result = Some(sum); 30 | } 31 | 32 | fn print(self) { 33 | match self.result { 34 | Some(x) => println!("{}", x), 35 | None => println!("Assert!"), 36 | } 37 | } 38 | } 39 | 40 | fn main(){ 41 | let seed = stdinln_i32(); 42 | let mut problem = SumAndSum::new(seed); 43 | // SumAndSum::calc() 를 완성해주세요! 44 | problem.calc(); 45 | problem.print(); 46 | } -------------------------------------------------------------------------------- /chapter01/problem_j/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | 7 | /** 8 | * 1부터 N까지의 자연수의 합을 계산하는 함수 9 | * @param i 10 | * @return 11 | */ 12 | int getRangeSumFromOne(int i) { 13 | int sum = 0; 14 | 15 | for (int j = 1; j <= i; j += 1) { 16 | sum += j; 17 | } 18 | 19 | return sum; 20 | } 21 | 22 | 23 | long long getAnswer(int N) { 24 | long answer = 0; 25 | for (int i = 1; i <= N; i++) { 26 | int rangeSum = getRangeSumFromOne(i); 27 | answer += rangeSum; 28 | } 29 | 30 | return answer; 31 | } 32 | 33 | int main() { 34 | int n; 35 | 36 | scanf("%d", &n); 37 | 38 | long long answer = getAnswer(n); 39 | 40 | printf("%lld\n", answer); 41 | 42 | return 0; 43 | } -------------------------------------------------------------------------------- /chapter02/problem_a/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | /** 9 | * 생일이 m월인 가장 큰 키의 도토리를 찾는 함수 10 | * @param height 각 도토리의 키 11 | * @param month 각 도토리의 출생 월 12 | * @param n 도토리의 수 13 | * @param m 찾고자 하는 달 14 | * @return month[k] == m인 가장 큰 height[k] 15 | */ 16 | public static int getMaximumHeight(int[] height, int[] month, int n, int m) 17 | { 18 | int maxHeight = -1; //생일이 m월인 사람이 아무도 없다면 -1일 것이다. 19 | 20 | for(int i = n-1; i>=0 ; i-=1) 21 | { //모든 도토리의 출생 월 month[i]에 대해 22 | //키가 큰 도토리부터 고려하다가 23 | if(month[i] == m) 24 | { // 생일이 일치하는 도토리가 등장했다! 저장하자 25 | maxHeight = height[i]; 26 | 27 | //그 이후 (i가 작아지는 방향)에는 어차피 더 큰 키의 사람이 없다. 28 | //그러므로 더 수행할 필요가 없음이 자명하다. 29 | break; 30 | } 31 | } 32 | 33 | return maxHeight; 34 | } 35 | 36 | public static void main(String[] args) throws Exception { 37 | int n = scanner.nextInt(); 38 | int[] height = new int[n]; 39 | int[] month = new int[n]; 40 | 41 | for(int i = 0 ; i < n ; i ++) 42 | { 43 | height[i] = scanner.nextInt(); 44 | } 45 | 46 | for (int i = 0; i < n; i++) { 47 | month[i] = scanner.nextInt(); 48 | } 49 | 50 | int m = scanner.nextInt(); 51 | 52 | int answer = getMaximumHeight(height, month, n, m); 53 | 54 | System.out.println(answer); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /chapter02/problem_a/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn stdinln_i32() -> i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn stdinln_vec_i32() -> Vec { 11 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 12 | let mut buffer = String::new(); 13 | std::io::stdin().read_line(&mut buffer).expect("Failed to read line"); 14 | let ret: Vec = buffer.split(" ") 15 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 16 | .collect(); 17 | ret 18 | } 19 | 20 | fn solve(nr_case: usize, heights: &Vec, births: &Vec, match_birth: i32) -> Option { 21 | let mut tallest :i32 = -1; 22 | for i in 0..nr_case{ 23 | if births[i] == match_birth { 24 | if heights[i] > tallest { 25 | tallest = heights[i]; 26 | } 27 | } 28 | } 29 | 30 | if tallest >= 0 { 31 | Some(tallest) 32 | }else { 33 | None 34 | } 35 | } 36 | 37 | fn main(){ 38 | let nr_case = stdinln_i32() as usize; 39 | let heights = stdinln_vec_i32(); 40 | let births = stdinln_vec_i32(); 41 | let match_birth = stdinln_i32(); 42 | let result = solve(nr_case, &heights, &births, match_birth); 43 | match result { 44 | Some(x) => println!("{}", x), 45 | None => println!("{}", -1), 46 | } 47 | } -------------------------------------------------------------------------------- /chapter02/problem_a/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | /** 7 | * 생일이 m월인 가장 큰 키의 도토리를 찾는 함수 8 | * @param height 각 도토리의 키 9 | * @param month 각 도토리의 출생 월 10 | * @param n 도토리의 수 11 | * @param m 찾고자 하는 달 12 | * @return month[k] == m인 가장 큰 height[k] 13 | */ 14 | int getMaximumHeight(int height[], int month[], int n, int m) { 15 | int maxHeight = -1; //생일이 m월인 사람이 아무도 없다면 -1일 것이다. 16 | 17 | for (int i = n - 1; i >= 0; i -= 1) { //모든 도토리의 출생 월 month[i]에 대해 18 | //키가 큰 도토리부터 고려하다가 19 | if (month[i] == m) { // 생일이 일치하는 도토리가 등장했다! 저장하자 20 | maxHeight = height[i]; 21 | 22 | //그 이후 (i가 작아지는 방향)에는 어차피 더 큰 키의 사람이 없다. 23 | //그러므로 더 수행할 필요가 없음이 자명하다. 24 | break; 25 | } 26 | } 27 | 28 | return maxHeight; 29 | } 30 | 31 | int main() { 32 | int n, m; 33 | int *height; 34 | int *month; 35 | 36 | scanf("%d", &n); 37 | height = new int[n]; 38 | month = new int[n]; 39 | 40 | for (int i = 0; i < n; i++) { 41 | scanf("%d", &height[i]); 42 | } 43 | 44 | for (int i = 0; i < n; i++) { 45 | scanf("%d", &month[i]); 46 | } 47 | 48 | scanf("%d", &m); 49 | 50 | int answer = getMaximumHeight(height, month, n, m); 51 | 52 | printf("%d\n", answer); 53 | 54 | delete[] height; 55 | delete[] month; 56 | return 0; 57 | } -------------------------------------------------------------------------------- /chapter02/problem_a/solution.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # UTF-8 encoding when using korean 3 | 4 | from typing import List 5 | 6 | 7 | def get_maximum_height(heights: List[int], months: List[int], m: int) -> int: 8 | """ 9 | 생일이 m월인 가장 큰 키의 도토리를 찾는 함수 10 | :param heights: 각 도토리의 키 11 | :param months: 각 도토리의 달 12 | :param m: 찾을 생일이 속한 달 13 | :return: 해당 달에 속한 도토리의 가장 큰 키 14 | """ 15 | n = len(heights) 16 | answer = -1 # 존재하지 않으면 -1 17 | 18 | for i in range(n - 1, -1, -1): # 오름차순이므로 뒤에서부터 탐색 19 | if months[i] == m: 20 | answer = heights[i] 21 | break # 찾았으면 더이상 탐색할 필요 없음 22 | 23 | return answer 24 | 25 | 26 | if __name__ == "__main__": 27 | # 데이터의 수를 입력받는다 28 | n = int(input()) 29 | heights = [int(w) for w in input().split()] 30 | months = [int(w) for w in input().split()] 31 | m = int(input()) 32 | answer = get_maximum_height(heights, months, m) 33 | print(answer) 34 | -------------------------------------------------------------------------------- /chapter02/problem_b/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | /** 10 | * 주어진 배열이 오름차순인지 검사하는 함수 11 | * @param data 12 | * @param n 데이터의 수 13 | * @return data[0] ~ data[n-1]이 오름차순이라면 true, else false 14 | */ 15 | public static boolean isOrdered(int[] data, int n) 16 | { 17 | int count = 0; //오름차순을 부정하는 페어의 수 -> data[i] > data[i+1]; 18 | 19 | for(int i = 0 ; i + 1 < n ; i++) 20 | { 21 | if(data[i] > data[i+1]) 22 | { 23 | count += 1; 24 | break; 25 | } 26 | } 27 | 28 | if(count >= 1) 29 | { 30 | return false; 31 | }else{ 32 | return true; 33 | } 34 | } 35 | 36 | 37 | public static void main(String[] args) throws Exception { 38 | int n = scanner.nextInt(); 39 | int[] data = new int[n]; 40 | 41 | for(int i = 0 ; i < n ; i++) 42 | { 43 | data[i] = scanner.nextInt(); 44 | } 45 | 46 | boolean result = isOrdered(data, n); 47 | 48 | if(result) 49 | { 50 | System.out.println("YES"); 51 | }else{ 52 | System.out.println("NO"); 53 | } 54 | 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /chapter02/problem_b/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn stdinln_i32() -> i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn stdinln_vec_i32() -> Vec { 11 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 12 | let mut buffer = String::new(); 13 | std::io::stdin().read_line(&mut buffer).expect("Failed to read line"); 14 | let ret: Vec = buffer.split(" ") 15 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 16 | .collect(); 17 | ret 18 | } 19 | 20 | 21 | fn is_sorted(nr_case: usize, heights: &Vec) -> bool { 22 | // is_sorted를 완성해주세요. 오름차순이면 true, 아닌 경우 false를 리턴해주세요. 23 | let mut ret: bool = true; 24 | for i in 1..nr_case { 25 | if heights[i] < heights[i-1] { 26 | ret = false; 27 | break; 28 | } 29 | } 30 | ret 31 | } 32 | 33 | fn main(){ 34 | let nr_case = stdinln_i32() as usize; 35 | let heights = stdinln_vec_i32(); 36 | // is_sorted를 완성해주세요! 37 | let result: bool = is_sorted(nr_case, &heights); 38 | match result { 39 | true => println!("YES"), 40 | false => println!("NO"), 41 | } 42 | } -------------------------------------------------------------------------------- /chapter02/problem_b/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | /** 7 | * 주어진 배열이 오름차순인지 검사하는 함수 8 | * @param data 9 | * @param n 데이터의 수 10 | * @return data[0] ~ data[n-1]이 오름차순이라면 true, else false 11 | */ 12 | bool isOrdered(int data[], int n) { 13 | int count = 0; //오름차순을 부정하는 페어의 수 -> data[i] > data[i+1]; 14 | 15 | for (int i = 0; i + 1 < n; i++) { 16 | if (data[i] > data[i + 1]) { 17 | count += 1; 18 | break; 19 | } 20 | } 21 | 22 | if (count >= 1) { 23 | return false; 24 | } else { 25 | return true; 26 | } 27 | } 28 | 29 | int main() { 30 | int n; 31 | int *data; 32 | 33 | scanf("%d", &n); 34 | data = new int[n]; 35 | 36 | for (int i = 0; i < n; i++) { 37 | scanf("%d", &data[i]); 38 | } 39 | 40 | bool result = isOrdered(data, n); 41 | 42 | if (result) { 43 | printf("YES"); 44 | } else { 45 | printf("NO"); 46 | } 47 | 48 | delete[] data; 49 | return 0; 50 | } -------------------------------------------------------------------------------- /chapter02/problem_b/solution.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # UTF-8 encoding when using korean 3 | 4 | from typing import List 5 | 6 | 7 | def is_ordered(data: List[int]) -> bool: 8 | """ 9 | 주어진 배열이 오름차순으로 정렬되어있는지 검사하는 함수 10 | :param data: 정수 배열 11 | :return: 정렬된 상태라면 True, 아니라면 False 12 | """ 13 | n = len(data) 14 | for i in range(1, n): 15 | if data[i - 1] > data[i]: 16 | return False 17 | 18 | return True 19 | 20 | 21 | if __name__ == "__main__": 22 | n = int(input()) 23 | data = [int(w) for w in input().split()] 24 | print(f'{"YES" if is_ordered(data) else "NO"}') 25 | -------------------------------------------------------------------------------- /chapter02/problem_c/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | /** 10 | * 중복을 제외한 숫자의 종류의 수를 계산하는 함수 11 | * @param data 원본 배열 12 | * @param n 원본 배열의 크기 13 | * @return 숫자의 종류의 수 14 | */ 15 | public static int getElementTypeCount(int[] data, int n) 16 | { 17 | int countType = 0; 18 | for(int i = 0 ; i < n ; i ++) 19 | { 20 | if(i == 0 || data[i-1] != data[i]) 21 | { // data[i]와 같은 숫자가 처음으로 등장했다면 22 | // 가짓수를 하나 증가시킨다 23 | countType += 1; 24 | } 25 | } 26 | return countType; 27 | } 28 | 29 | public static void main(String[] args) throws Exception { 30 | int n = scanner.nextInt(); 31 | int[] data = new int[n]; 32 | for(int i = 0 ; i < n ; i++) 33 | { 34 | data[i] = scanner.nextInt(); 35 | } 36 | 37 | int answer= getElementTypeCount(data, n); 38 | 39 | System.out.println(answer); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /chapter02/problem_c/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn stdinln_i32() -> i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn stdinln_vec_i32() -> Vec { 11 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 12 | let mut buffer = String::new(); 13 | std::io::stdin().read_line(&mut buffer).expect("Failed to read line"); 14 | let ret: Vec = buffer.split(" ") 15 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 16 | .collect(); 17 | ret 18 | } 19 | 20 | fn count_kinds(nr_case: usize, numbers: &Vec) -> u32 { 21 | // count_kinds 완성해주세요. 음수는 절대로 올 수 없기에 u32로 리턴해줍시다. 22 | // 종류 갯수가 만약 입력값이 비어있는 경우에는 1이 될수가 없다. 23 | let mut ret: u32 = { 24 | if nr_case == 0 && numbers.len() == 0 { 25 | 0 26 | }else { 27 | 1 28 | } 29 | }; 30 | 31 | for i in 1..nr_case { 32 | if numbers[i-1] != numbers[i] { 33 | ret += 1; 34 | } 35 | } 36 | ret 37 | } 38 | 39 | fn main(){ 40 | let nr_case = stdinln_i32() as usize; 41 | let numbers = stdinln_vec_i32(); 42 | // count_kinds를 완성해주세요! 43 | let result: u32= count_kinds(nr_case, &numbers); 44 | println!("{}", result) 45 | } -------------------------------------------------------------------------------- /chapter02/problem_c/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | /** 7 | * 중복을 제외한 숫자의 종류의 수를 계산하는 함수 8 | * @param data 원본 배열 9 | * @param n 원본 배열의 크기 10 | * @return 숫자의 종류의 수 11 | */ 12 | int getElementTypeCount(int data[], int n) { 13 | int countType = 0; 14 | for (int i = 0; i < n; i++) { 15 | if (i == 0 || data[i - 1] != data[i]) { 16 | countType += 1; 17 | } 18 | } 19 | 20 | return countType; 21 | } 22 | 23 | int main() { 24 | int n; 25 | int *data; 26 | 27 | scanf("%d", &n); 28 | data = new int[n]; 29 | 30 | for (int i = 0; i < n; i++) { 31 | scanf("%d", &data[i]); 32 | } 33 | 34 | int answer = getElementTypeCount(data, n); 35 | 36 | printf("%d\n", answer); 37 | 38 | delete[] data; 39 | return 0; 40 | } -------------------------------------------------------------------------------- /chapter02/problem_c/solution.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # UTF-8 encoding when using korean 3 | 4 | from typing import List 5 | 6 | 7 | def get_element_type_count(data: List[int]) -> int: 8 | """ 9 | 중복을 제외한 숫자의 종류의 수를 계산하는 함수 10 | :param data: 정수 배열 11 | :return: 원소의 종류의 수 12 | """ 13 | n = len(data) 14 | count = 1 15 | for i in range(1, n): 16 | if data[i - 1] != data[i]: 17 | count += 1 18 | return count 19 | 20 | 21 | if __name__ == "__main__": 22 | n = int(input()) 23 | data = [int(w) for w in input().split()] 24 | answer = get_element_type_count(data) 25 | print(answer) 26 | -------------------------------------------------------------------------------- /chapter02/problem_d/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | enum RetStrcmp { 4 | left_upper, 5 | right_upper, 6 | equal, 7 | } 8 | 9 | fn custom_strcmp(left: &[u8], right: &[u8]) -> RetStrcmp { 10 | // custom_strcmp 완성해주세요. "RetStrcmp" enum에 맞게 풀어봅시다. 11 | // 구름IDE의 rustc 가 구버젼이라 안됨. let max_iter = left.len().min(right.len()); 12 | let max_iter = { 13 | if left.len() > right.len() { 14 | right.len() 15 | }else { 16 | left.len() 17 | } 18 | }; 19 | // end of alternative code for usize::min(self, other) 20 | 21 | let mut i = 0; 22 | loop { 23 | if !(i < max_iter - 1) { 24 | break; 25 | } 26 | 27 | if left[i] != right[i] { 28 | break; 29 | }else{ 30 | i += 1; 31 | } 32 | } 33 | 34 | if left[i] > right[i] { 35 | RetStrcmp::right_upper 36 | } else if left[i] < right[i] { 37 | RetStrcmp::left_upper 38 | }else { 39 | if left.len() > right.len() { 40 | RetStrcmp::right_upper 41 | }else if left.len() < right.len() { 42 | RetStrcmp::left_upper 43 | }else { 44 | RetStrcmp::equal 45 | } 46 | } 47 | 48 | } 49 | 50 | fn main(){ 51 | let mut str_left = String::new(); 52 | let mut str_right = String::new(); 53 | std::io::stdin().read_line(&mut str_left).expect("Failed to read line"); 54 | std::io::stdin().read_line(&mut str_right).expect("Failed to read line"); 55 | let bleft = str_left.trim().as_bytes(); 56 | let bright = str_right.trim().as_bytes(); 57 | // custom_strcmp를 완성해주세요! 58 | // 이번에는 match + enu조합으로 되어있습니다. 59 | let result : i32 = match custom_strcmp(&bleft, &bright) { 60 | RetStrcmp::left_upper => -1, 61 | RetStrcmp::right_upper => 1, 62 | RetStrcmp::equal => 0, 63 | }; 64 | println!("{}", result) 65 | } -------------------------------------------------------------------------------- /chapter02/problem_e/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | /** 10 | * 주어진 숫자가 소수인지 판별하는 함수 11 | * 12 | * @param N 13 | * @return true 소수라면 14 | * @return false 소수가 아니라면 15 | */ 16 | public static boolean isPrime(int N) 17 | { 18 | if( N == 1) return false; //1은 소수가 아니다 19 | else if( N == 2 ) return true; //2는 소수다 20 | else if( N % 2 == 0) return false; //나머지 짝수는 소수가 아니다 21 | 22 | for(int i = 3; i*i <= N; i+=2) 23 | { //모든 N미만의 홀수 자연수 i에 대해 24 | if( N % i == 0 ) 25 | { //이 범위에 약수가 존재한다면 소수일 수 없다. 26 | return false; 27 | } 28 | } 29 | //약수가 하나도 존재하지 않았다면. 30 | return true; 31 | } 32 | 33 | public static void testCase(int caseIndex) 34 | { 35 | int n = scanner.nextInt(); 36 | boolean result = isPrime(n); 37 | 38 | System.out.printf("Case #%d\n", caseIndex); 39 | if(result) 40 | { 41 | System.out.println("YES"); 42 | }else{ 43 | System.out.println("NO"); 44 | } 45 | } 46 | 47 | public static void main(String[] args) throws Exception { 48 | int caseSize = scanner.nextInt(); 49 | 50 | for (int caseIndex = 1; caseIndex <= caseSize; caseIndex += 1) { 51 | testCase(caseIndex); 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /chapter02/problem_e/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn stdinln_i32() -> i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn is_prime(target: i32) -> bool { 11 | // is_prime을 완성시켜주세요. 소수인 경우 true, 아닌경우 false를 리턴해주세요. 12 | if target == 1 { 13 | false 14 | } 15 | else if target == 2 { 16 | true 17 | }else if target & 0x1 == 0 { 18 | false 19 | }else { 20 | let mut ret = true; 21 | let max_iter = ((target as f64).sqrt() + 1.0) as usize; 22 | let mut i = 3; 23 | loop { 24 | if !(i < max_iter){ 25 | break; 26 | } 27 | if target%(i as i32) == 0 { 28 | ret = false; 29 | break; 30 | } 31 | 32 | i += 2; 33 | } 34 | ret 35 | } 36 | } 37 | 38 | fn main() { 39 | let nr_case = stdinln_i32() as usize; 40 | let mut testcase = Vec::new(); 41 | for i in 0..nr_case { 42 | testcase.push(stdinln_i32()); 43 | } 44 | 45 | for i in 0..nr_case { 46 | println!("Case #{}", i+1); 47 | // is_prime을 완성시켜주세요!. 48 | match is_prime(testcase[i]) { 49 | true => println!("YES"), 50 | false => println!("NO"), 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /chapter02/problem_e/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | /** 7 | * 주어진 숫자가 소수인지 판별하는 함수 8 | * 9 | * @param N 10 | * @return true 소수라면 11 | * @return false 소수가 아니라면 12 | */ 13 | bool isPrime(int N) { 14 | if (N == 1) return false; //1은 소수가 아니다 15 | else if (N == 2) return true; //2는 소수다 16 | else if (N % 2 == 0) return false; //나머지 짝수는 소수가 아니다 17 | 18 | for (int i = 3; i * i <= N; i += 2) { //모든 N미만의 홀수 자연수 i에 대해 19 | if (N % i == 0) { //이 범위에 약수가 존재한다면 소수일 수 없다. 20 | return false; 21 | } 22 | } 23 | //약수가 하나도 존재하지 않았다면. 24 | return true; 25 | } 26 | 27 | void testcase(int caseIndex) { 28 | int n; 29 | scanf("%d", &n); 30 | 31 | bool result = isPrime(n); 32 | 33 | printf("Case #%d\n", caseIndex); 34 | if (result) { 35 | printf("YES\n"); 36 | } else { 37 | printf("NO\n"); 38 | } 39 | } 40 | 41 | int main() { 42 | int caseSize; 43 | scanf("%d", &caseSize); 44 | for (int caseIndex = 1; caseIndex <= caseSize; caseIndex += 1) { 45 | testcase(caseIndex); 46 | } 47 | return 0; 48 | } -------------------------------------------------------------------------------- /chapter02/problem_e/solution.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # UTF-8 encoding when using korean 3 | 4 | 5 | def is_prime(n: int) -> bool: 6 | """ 7 | 주어진 숫자가 소수인지 판별하는 함수 8 | :param n: 판별할 정수 9 | :return: 소수면 True, 아니면 False 10 | """ 11 | if n == 1: return False 12 | if n == 2: return True 13 | if n % 2 == 0: return False 14 | for i in range(3, int(n ** 0.5) + 1, 2): 15 | if n % i == 0: return False 16 | return True 17 | 18 | 19 | if __name__ == "__main__": 20 | case_size = int(input()) 21 | for i in range(case_size): 22 | n = int(input()) 23 | print(f"Case #{i + 1}") 24 | print(f"{'YES' if is_prime(n) else 'NO'}") 25 | -------------------------------------------------------------------------------- /chapter02/problem_f/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | public static void main(String[] args) { 10 | int n = scanner.nextInt(); 11 | Point2D[] points = new Point2D[n]; 12 | 13 | for (int i = 0; i < n; i++) { 14 | int x = scanner.nextInt(); 15 | int y = scanner.nextInt(); 16 | points[i] = new Point2D(x, y); 17 | } 18 | 19 | int min_sqd = Integer.MAX_VALUE; 20 | int min_cnt = 0; 21 | 22 | for (int i = 0; i < n; i++) { 23 | for (int j = 0; j < i; j++) { 24 | // i에 대하여 25 | int sqd = points[i].getSquaredDistanceTo(points[j]); 26 | if (sqd < min_sqd) { 27 | // 현재까지 찾은 거리들 중 가장 작다면, 최소 거리를 갱신한다 28 | min_sqd = sqd; 29 | min_cnt = 1; 30 | } else if (sqd == min_sqd) { 31 | // 최소 거리와 같은 거리를 가지는 쌍을 찾는다면 32 | // 해당 거리의 빈도수를 증가시킨다 33 | min_cnt++; 34 | } 35 | } 36 | } 37 | 38 | double distance = Math.sqrt(min_sqd); 39 | System.out.printf("%.1f\n", distance); 40 | System.out.println(min_cnt); 41 | } 42 | } 43 | 44 | class Point2D { 45 | int x; 46 | int y; 47 | 48 | public Point2D(int x, int y) { 49 | this.x = x; 50 | this.y = y; 51 | } 52 | 53 | /** 54 | * @param target 55 | * @return 56 | * @brief 2차원 평면 상에서 점 this부터 점 target까지 거리의 제곱을 계산하는 함수 57 | */ 58 | public int getSquaredDistanceTo(Point2D target) { 59 | int dx = Math.abs(target.x - this.x); 60 | int dy = Math.abs(target.y - this.y); 61 | return dx * dx + dy * dy; 62 | } 63 | 64 | /** 65 | * @param target 66 | * @return 67 | * @brief 2차원 평면 상에서 점 this부터 점 target까지 거리를 계산하는 함수 68 | */ 69 | public double getDistanceTo(Point2D target) { 70 | double sqd = (double) this.getSquaredDistanceTo(target); 71 | return Math.sqrt(sqd); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /chapter02/problem_f/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | class Point2D { 9 | private: 10 | int x; 11 | int y; 12 | 13 | public: 14 | Point2D(int x = 0, int y = 0) { 15 | this->x = x; 16 | this->y = y; 17 | } 18 | 19 | /** 20 | * 2차원 평면 상에서 점 this부터 점 target까지 거리의 제곱을 계산하는 함수 21 | * @param target 22 | * @return 23 | */ 24 | int getSquaredDistanceTo(const Point2D &target) const { 25 | int dx = abs(this->x - target.x); 26 | int dy = abs(this->y - target.y); 27 | return dx * dx + dy * dy; 28 | } 29 | 30 | double getDistanceTo(const Point2D &target) const { 31 | double sqd = (double) this->getSquaredDistanceTo(target); 32 | return sqrt(sqd); 33 | } 34 | }; 35 | 36 | 37 | int main() { 38 | int n; 39 | Point2D *points; 40 | 41 | scanf("%d", &n); 42 | points = new Point2D[n]; 43 | 44 | for (int i = 0; i < n; i++) { 45 | int x, y; 46 | scanf("%d %d", &x, &y); 47 | 48 | points[i] = Point2D(x, y); 49 | } 50 | 51 | int min_sqd = INT_MAX; 52 | int min_cnt = 0; 53 | 54 | for (int i = 0; i < n; i++) { 55 | for (int j = 0; j < i; j++) { 56 | int sqd = points[i].getSquaredDistanceTo(points[j]); 57 | if (sqd < min_sqd) { 58 | min_sqd = sqd; 59 | min_cnt = 1; 60 | } else if (sqd == min_sqd) { 61 | min_cnt++; 62 | } 63 | } 64 | } 65 | 66 | double distance = sqrt(min_sqd); 67 | printf("%.1f\n", distance); 68 | printf("%d\n", min_cnt); 69 | 70 | delete[] points; 71 | return 0; 72 | } -------------------------------------------------------------------------------- /chapter02/problem_f/solution.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # UTF-8 encoding when using korean 3 | 4 | import math 5 | from typing import List, Tuple 6 | 7 | 8 | class point2d: 9 | def __init__(self, x: int = 0, y: int = 0): 10 | self.x: int = x 11 | self.y: int = y 12 | 13 | def get_squared_dist(self, other: "point2d") -> int: 14 | """ 15 | 두 점(self, other) 사이의 거리의 제곱을 반환합니다. 16 | :param other: 다른 점 17 | :return: 두 점 사이의 거리의 제곱 18 | """ 19 | return (self.x - other.x) ** 2 + (self.y - other.y) ** 2 20 | 21 | def get_dist(self, other: "point2d") -> float: 22 | """ 23 | 두 점(self, other) 사이의 거리를 반환합니다. 24 | :param other: 다른 점 25 | :return: 두 점 사이의 거리 26 | """ 27 | return math.sqrt(self.get_squared_dist(other)) 28 | 29 | 30 | def closest_pair(points: List[point2d]) -> Tuple[float, int]: 31 | """ 32 | 주어진 점들 중 가장 가까운 두 점 사이의 거리를 반환합니다. 33 | :param points: 점들의 리스트 34 | :return: 가장 가까운 두 점 사이의 거리 35 | """ 36 | min_dist = -1 # 가장 가까운 쌍의 거리 37 | min_count: int = -1 # 가장 가까운 쌍의 수 38 | n = len(points) 39 | 40 | for i in range(n): 41 | for j in range(i + 1, n): # 같은 쌍, 중복 쌍을 무시하기 위해 i+1부터 시작 42 | dist = points[i].get_squared_dist(points[j]) 43 | if min_dist == -1 or dist < min_dist: # 처음이거나 더 작은 거리를 찾은 경우 44 | min_dist = dist 45 | min_count = 1 46 | elif dist == min_dist: # 같은 거리를 가진 쌍을 찾은 경우 47 | min_count += 1 48 | 49 | return math.sqrt(min_dist), min_count 50 | 51 | 52 | def main(): 53 | n = int(input()) 54 | points: List[point2d] = [] 55 | for i in range(n): 56 | x, y = [int(w) for w in input().split()] 57 | points.append(point2d(x, y)) 58 | min_dist, min_count = closest_pair(points) 59 | print(f"{min_dist:.1f}") 60 | print(min_count) 61 | 62 | 63 | if __name__ == "__main__": 64 | main() 65 | -------------------------------------------------------------------------------- /chapter02/problem_g/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | public static void bubbleSort(int[] data, int n) 10 | { 11 | for(int i = 0 ; i < n ; i++) 12 | { 13 | int negativeCount = 0; 14 | for(int j = 0 ; j < n - 1- i; j ++) 15 | { 16 | //오름차순을 부정하는 쌍이 등장하며면 17 | if( data[j] > data[j+1] ) 18 | { //두 쌍의 자리를 변경한다 19 | int temp = data[j]; 20 | data[j] = data[j+1]; 21 | data[j+1] = temp; 22 | 23 | //그리고 그런 쌍의 수를 기록한다 24 | negativeCount += 1; 25 | } 26 | } 27 | 28 | //이 값이 0이라는 건? 이미 모두 정렬이 되었다는 것 29 | if(negativeCount == 0) 30 | { 31 | break; 32 | } 33 | } 34 | } 35 | 36 | public static void main(String[] args) throws Exception { 37 | int n = scanner.nextInt(); 38 | int[] data = new int[n]; 39 | for(int i = 0 ; i < n ; i++) 40 | { 41 | data[i] = scanner.nextInt(); 42 | } 43 | 44 | bubbleSort(data, n); 45 | 46 | for(int i = 0 ; i < n ; i++) 47 | { 48 | if( i > 0 ) 49 | { 50 | System.out.print(" "); 51 | } 52 | System.out.print(data[i]); 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /chapter02/problem_g/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn stdinln_i32() -> i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn stdinln_vec_i32() -> Vec { 11 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 12 | let mut buffer = String::new(); 13 | std::io::stdin().read_line(&mut buffer).expect("Failed to read line"); 14 | let ret: Vec = buffer.split(" ") 15 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 16 | .collect(); 17 | ret 18 | } 19 | 20 | struct Bubble { 21 | data: Vec, 22 | nr_item: usize 23 | } 24 | 25 | impl Bubble { 26 | fn new_from_vec_i32(inputs: Vec, len: usize) -> Bubble { 27 | Bubble{data:inputs, nr_item: len} 28 | } 29 | 30 | fn sort(&mut self) { 31 | // Bubble::sort() 를 완성해주세요. 32 | for i in 0..self.nr_item { 33 | for j in 1..self.nr_item { 34 | if self.data[j-1] > self.data[j] { 35 | let temp = self.data[j-1]; 36 | self.data[j-1] = self.data[j]; 37 | self.data[j] = temp; 38 | } 39 | } 40 | } 41 | // end of Bubble::sort() 42 | } 43 | 44 | fn print(self) { 45 | for item in self.data { 46 | print!("{} ", item); 47 | } 48 | println!(""); 49 | } 50 | } 51 | 52 | fn main() { 53 | let nr_item = stdinln_i32() as usize; 54 | let mut problem = Bubble::new_from_vec_i32(stdinln_vec_i32(), nr_item); 55 | // Bubble::sort() 를 완성해주세요. 56 | problem.sort(); 57 | problem.print(); 58 | } -------------------------------------------------------------------------------- /chapter02/problem_g/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | 7 | void bubbleSort(int data[], int n) { 8 | for (int i = 0; i < n; i++) { 9 | int negativeCount = 0; 10 | for (int j = 0; j < n - 1 - i; j++) { 11 | //오름차순을 부정하는 쌍이 등장하며면 12 | if (data[j] > data[j + 1]) { //두 쌍의 자리를 변경한다 13 | int temp = data[j]; 14 | data[j] = data[j + 1]; 15 | data[j + 1] = temp; 16 | 17 | //그리고 그런 쌍의 수를 기록한다 18 | negativeCount += 1; 19 | } 20 | } 21 | 22 | //이 값이 0이라는 건? 이미 모두 정렬이 되었다는 것 23 | if (negativeCount == 0) { 24 | break; 25 | } 26 | } 27 | } 28 | 29 | int main() { 30 | int n; 31 | int *data; 32 | 33 | scanf("%d", &n); 34 | data = new int[n]; 35 | 36 | for (int i = 0; i < n; i++) { 37 | scanf("%d", &data[i]); 38 | } 39 | 40 | bubbleSort(data, n); 41 | 42 | for (int i = 0; i < n; i++) { 43 | if (i > 0) { 44 | printf(" "); 45 | } 46 | printf("%d", data[i]); 47 | } 48 | 49 | delete[] data; 50 | return 0; 51 | } -------------------------------------------------------------------------------- /chapter02/problem_g/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | def bubble_sort(data: List[int]): 5 | """ 6 | 선택 정렬을 수행한다. 7 | :param data: 정수 배열 8 | """ 9 | n = len(data) 10 | 11 | for i in range(n - 1): # Pair로 검사하므로 마지막 칸 제외 12 | for j in range(n - i - 1): # 반복 횟수만큼 마지막 원소들은 이미 정렬되어 있다 13 | if data[j] > data[j + 1]: 14 | data[j], data[j + 1] = data[j + 1], data[j] 15 | 16 | 17 | if __name__ == "__main__": 18 | n = int(input()) 19 | data = [int(w) for w in input().split()] 20 | bubble_sort(data) 21 | print(' '.join([str(w) for w in data])) 22 | -------------------------------------------------------------------------------- /chapter02/problem_h/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | /** 10 | * 왼쪽 아래 좌표가 (x,y)인 픽셀이 반지름 R인 원에 포함되는가? 11 | * @param x 12 | * @param y 13 | * @param R 14 | * @return 포함된다면 true, else false 15 | */ 16 | public static boolean isInside(long x, long y, long R) 17 | { 18 | long sqd = x *x + y * y ; //거리의 제곱 19 | if ( sqd < R * R ) //반지름의 제곱 20 | { //원점과의 거리가 반지름보다 작다면, 원 안에 있다. 21 | return true; 22 | } 23 | return false; 24 | } 25 | 26 | public static void testCase(int caseIndex) { 27 | long R = scanner.nextLong(); 28 | 29 | long sum = 0; //1사분면에 존재하는 총 픽셀의 수 30 | long y = R; 31 | for(long x = 0 ; x <= R; x ++) 32 | { 33 | long height = 0; 34 | for( ; y >= 0; y --) 35 | { 36 | if(isInside(x, y, R)) 37 | { //위에서 부터 내려오다가 38 | //가장 최초로 원 안에 포함된 픽셀 (x, y) 39 | //이 그룹의 높이는 (y+1)이 된다. 40 | height = (y+1); 41 | break; 42 | } 43 | } 44 | 45 | sum += height; //너비는 1이므로 46 | } 47 | 48 | System.out.printf("#%d\n", caseIndex); 49 | System.out.printf("%d\n", sum * 4); //모든 사분면의 픽셀 수 50 | } 51 | 52 | public static void main(String[] args) throws Exception { 53 | int caseSize = scanner.nextInt(); 54 | 55 | for (int caseIndex = 1; caseIndex <= caseSize; caseIndex += 1) { 56 | testCase(caseIndex); 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /chapter02/problem_h/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | /** 7 | * 왼쪽 아래 좌표가 (x,y)인 픽셀이 반지름 R인 원에 포함되는가? 8 | * @param x 9 | * @param y 10 | * @param R 11 | * @return 포함된다면 true, else false 12 | */ 13 | bool isInside(long long x, long long y, long long R) { 14 | long long sqd = x * x + y * y; //거리의 제곱 15 | if (sqd < R * R) //반지름의 제곱 16 | { //원점과의 거리가 반지름보다 작다면, 원 안에 있다. 17 | return true; 18 | } 19 | return false; 20 | } 21 | 22 | void testcase(int caseIndex) { 23 | long long R; 24 | scanf("%lld", &R); 25 | 26 | long long sum = 0; //1사분면에 존재하는 총 픽셀의 수 27 | long long y = R; 28 | for (long x = 0; x <= R; x++) { 29 | long long height = 0; 30 | for (; y >= 0; y--) { 31 | if (isInside(x, y, R)) { //위에서 부터 내려오다가 32 | //가장 최초로 원 안에 포함된 픽셀 (x, y) 33 | //이 그룹의 높이는 (y+1)이 된다. 34 | height = (y + 1); 35 | break; 36 | } 37 | } 38 | 39 | sum += height; //너비는 1이므로 40 | } 41 | 42 | 43 | printf("#%d\n", caseIndex); 44 | printf("%lld\n", sum * 4); //모든 사분면의 픽셀 수 45 | } 46 | 47 | int main() { 48 | int caseSize; 49 | scanf("%d", &caseSize); 50 | for (int caseIndex = 1; caseIndex <= caseSize; caseIndex += 1) { 51 | testcase(caseIndex); 52 | } 53 | return 0; 54 | } -------------------------------------------------------------------------------- /chapter02/problem_h/solution.py: -------------------------------------------------------------------------------- 1 | def is_inside(x: int, y: int, R: int) -> bool: 2 | """ 3 | 픽셀 (x, y)가 반지름이 R인 원에 포함되는지 여부를 반환하는 함수 4 | 5 | :param x: 정수 x 좌표 6 | :param y: 정수 y 좌표 7 | :param R: 정수 반지름 8 | :return: 픽셀이 원에 포함되면 True, 아니면 False 9 | """ 10 | return x ** 2 + y ** 2 < R ** 2 11 | 12 | 13 | def get_number_of_pixels(R: int) -> int: 14 | """ 15 | 반지름이 R인 원에 포함되는 픽셀의 수를 반환하는 함수 16 | 17 | :param R: 정수 반지름 18 | :return: 픽셀의 수 19 | """ 20 | 21 | pixels = 0 22 | h = R + 1 # 하강 검사를 시작할 높이 23 | for x in range(0, R + 1): 24 | for y in range(h, -1, -1): 25 | if is_inside(x, y, R): # (x, y)가 최초로 원에 포함되면 26 | pixels += y + 1 # 히스토그램의 높이를 더한다 27 | h = y 28 | break 29 | 30 | return pixels * 4 31 | 32 | 33 | if __name__ == "__main__": 34 | case_size = int(input()) 35 | for case_index in range(1, case_size + 1): 36 | radius = int(input()) 37 | print(f"#{case_index}") 38 | print(f"{get_number_of_pixels(radius)}") 39 | -------------------------------------------------------------------------------- /chapter02/problem_i/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | /** 10 | * 배열의 N개의 원소가 연속적인 정수 수열로 표현될 수 있는지 판단하는 함수 11 | * @param data 12 | * @param n 13 | * @return 14 | */ 15 | public static boolean isConsecutive(int[] data, int n) 16 | { 17 | int maximum = data[0]; 18 | int minimum = data[0]; 19 | 20 | for(int i = 0; i < n ; i++) 21 | { 22 | if(maximum < data[i]) 23 | { 24 | maximum = data[i]; 25 | } 26 | if(minimum > data[i]) 27 | { 28 | minimum = data[i]; 29 | } 30 | } 31 | 32 | if(maximum - minimum + 1 == n) 33 | { 34 | return true; 35 | }else{ 36 | return false; 37 | } 38 | } 39 | 40 | public static void main(String[] args) throws Exception { 41 | int n = scanner.nextInt(); 42 | int[] data = new int[n]; 43 | for(int i = 0 ; i < n ; i ++) 44 | { 45 | data[i] = scanner.nextInt(); 46 | } 47 | 48 | boolean result = isConsecutive(data, n); 49 | 50 | if(result) 51 | { 52 | System.out.println("YES"); 53 | }else{ 54 | System.out.println("NO"); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /chapter02/problem_i/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn stdinln_i32() -> i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn stdinln_vec_i32() -> Vec { 11 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 12 | let mut buffer = String::new(); 13 | std::io::stdin().read_line(&mut buffer).expect("Failed to read line"); 14 | let ret: Vec = buffer.split(" ") 15 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 16 | .collect(); 17 | ret 18 | } 19 | 20 | struct Netflix { 21 | watched : Vec, 22 | nr_watched : usize, 23 | } 24 | 25 | impl Netflix { 26 | fn new_from_vec_i32(inputs: Vec, len: usize) -> Netflix{ 27 | Netflix{watched: inputs, nr_watched: len} 28 | } 29 | 30 | fn is_contiguous(self) -> bool { 31 | // Netflix::is_contiguous() 를 완성해주세요! 32 | let mut minimum :i32 = 10000000; 33 | let mut maximum :i32 = 0; 34 | for i in 0..self.nr_watched { 35 | if minimum > self.watched[i] { 36 | minimum = self.watched[i]; 37 | } 38 | if maximum < self.watched[i] { 39 | maximum = self.watched[i]; 40 | } 41 | } 42 | 43 | let stretched = maximum - minimum + 1; 44 | if stretched as usize == self.nr_watched { 45 | true 46 | }else { 47 | false 48 | } 49 | // End of Netflix::is_contiguous() 50 | } 51 | } 52 | 53 | fn main() { 54 | let nr_scene = stdinln_i32() as usize; 55 | let mut maum_ui_sori = Netflix::new_from_vec_i32(stdinln_vec_i32(), nr_scene); 56 | // Netflix::is_contiguous()를 완성시켜주세요!. 57 | match maum_ui_sori.is_contiguous() { 58 | true => println!("YES"), 59 | false => println!("NO"), 60 | } 61 | } -------------------------------------------------------------------------------- /chapter02/problem_i/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | /** 7 | * 배열의 N개의 원소가 연속적인 정수 수열로 표현될 수 있는지 판단하는 함수 8 | * @param data 9 | * @param n 10 | * @return 11 | */ 12 | bool isConsecutive(int data[], int n) { 13 | int maximum = data[0]; 14 | int minimum = data[0]; 15 | 16 | for (int i = 0; i < n; i++) { 17 | if (maximum < data[i]) { 18 | maximum = data[i]; 19 | } 20 | if (minimum > data[i]) { 21 | minimum = data[i]; 22 | } 23 | } 24 | 25 | if (maximum - minimum + 1 == n) { 26 | return true; 27 | } else { 28 | return false; 29 | } 30 | } 31 | 32 | int main() { 33 | int n; 34 | int *data; 35 | 36 | scanf("%d", &n); 37 | data = new int[n]; 38 | for (int i = 0; i < n; i++) { 39 | scanf("%d", &data[i]); 40 | } 41 | 42 | bool result = isConsecutive(data, n); 43 | 44 | 45 | if (result) { 46 | printf("YES"); 47 | } else { 48 | printf("NO"); 49 | } 50 | 51 | delete[] data; 52 | return 0; 53 | } -------------------------------------------------------------------------------- /chapter02/problem_i/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | def is_consecutive(data: List[int]) -> bool: 5 | """ 6 | 주어진 정수 배열이 연속적인 정수를 포함하는지 확인하는 함수 7 | :param data: 정수 배열 8 | :return: 연속적인 정수를 포함하면 True, 아니면 False 9 | """ 10 | maximum = data[0] 11 | minimum = data[0] 12 | 13 | for d in data: 14 | maximum = max(maximum, d) 15 | minimum = min(minimum, d) 16 | 17 | if maximum - minimum + 1 == len(data): 18 | return True 19 | else: 20 | return False 21 | 22 | 23 | if __name__ == "__main__": 24 | n = int(input()) 25 | data = [int(w) for w in input().split()] 26 | print(f"{'YES' if is_consecutive(data) else 'NO'}") 27 | -------------------------------------------------------------------------------- /chapter02/problem_j/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | /** 10 | * 게임의 규칙에 따라 현무가 승리할 수 있는 경우의 수가 존재하는지 검사하는 함수 11 | * 12 | * @param data 13 | * @param n 14 | * @param k 15 | * @return true 현무가 승리할 수 있는 경우의 수가 하나 이상 존재한다면 16 | * @return false else 17 | */ 18 | public static boolean isWinnable(int[] data, int n, int k) { 19 | 20 | int winCount = 0; 21 | long sum = 0; 22 | 23 | // 첫 (k-1)개의 원소에 대한 합을 계산한다. 24 | for(int i = 0 ; i < k - 1 ; i++) 25 | { 26 | sum += data[i]; 27 | } 28 | 29 | for(int i = 0; i + k - 1 < n ; i++) 30 | { //영역의 왼쪽 끝 인덱스 i에 대해 31 | 32 | if(i > 0 ) 33 | { //영역을 벗어나게 되는 원소 제외 34 | sum -= data[i-1]; 35 | } 36 | 37 | //새로 영역에 들어온 원소 추가 38 | sum = sum + data[i + k-1]; 39 | 40 | if(sum % 2 == 0) 41 | { 42 | winCount += 1; 43 | 44 | //승리 가능한 지 여부만 중요하므로 탈출 45 | break; 46 | } 47 | } 48 | 49 | if(winCount > 0) 50 | { // 승리할 수 있는 경우의수가 하나라도 존재한다면 승리 가능하다 51 | return true; 52 | }else{ 53 | // 하나도 존재하지 않는다면 불가능하다 54 | return false; 55 | } 56 | } 57 | 58 | public static void main(String[] args) throws Exception { 59 | int n = scanner.nextInt(); 60 | int k = scanner.nextInt(); 61 | int[] data = new int[n]; 62 | for(int i = 0 ; i < n ; i++) 63 | { 64 | data[i] = scanner.nextInt(); 65 | } 66 | 67 | boolean result = isWinnable(data, n, k); 68 | 69 | if(result) 70 | { 71 | System.out.println("YES"); 72 | }else{ 73 | System.out.println("NO"); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /chapter02/problem_j/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn stdinln_i32() -> i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn stdinln_vec_i32() -> Vec { 11 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 12 | let mut buffer = String::new(); 13 | std::io::stdin().read_line(&mut buffer).expect("Failed to read line"); 14 | let ret: Vec = buffer.split(" ") 15 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 16 | .collect(); 17 | ret 18 | } 19 | 20 | fn solve(nr_cup :usize, contigious :usize, cups :Vec) -> bool { 21 | // solve를 완성시켜주세요. 22 | let mut ret :bool = false; 23 | let mut sum = 0; 24 | // 이문제는 아마 i32로는 안될겁니다. 25 | // 따라서 어차피 홀짝 체크이므로 0x1로 마스크로 하여 1이냐 0이냐만으로 홀짝체크합니다. 26 | for j in 0..contigious { 27 | sum += cups[j] & 0x1; 28 | } 29 | if sum & 0x1 != 0 { 30 | for i in 1..nr_cup-contigious+1 { 31 | sum -= cups[i-1] & 0x1; 32 | sum += cups[i+contigious-1] & 0x1; 33 | 34 | if sum & 0x1 == 0 { 35 | ret = true; 36 | break; 37 | } 38 | } 39 | }else { 40 | ret = true; 41 | } 42 | ret 43 | } 44 | 45 | 46 | fn main() { 47 | let spec = stdinln_vec_i32(); 48 | let result = solve(spec[0] as usize, spec[1] as usize, stdinln_vec_i32()); 49 | match result { 50 | true => println!("YES"), 51 | false => println!("NO"), 52 | } 53 | } -------------------------------------------------------------------------------- /chapter02/problem_j/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | /** 7 | * 게임의 규칙에 따라 현무가 승리할 수 있는 경우의 수가 존재하는지 검사하는 함수 8 | * 9 | * @param data 10 | * @param n 11 | * @param k 12 | * @return true 현무가 승리할 수 있는 경우의 수가 하나 이상 존재한다면 13 | * @return false else 14 | */ 15 | bool isWinnable(int data[], int n, int k) { 16 | 17 | int winCount = 0; 18 | long sum = 0; 19 | 20 | // 첫 (k-1)개의 원소에 대한 합을 계산한다. 21 | for (int i = 0; i < k - 1; i++) { 22 | sum += data[i]; 23 | } 24 | 25 | for (int i = 0; i + k - 1 < n; i++) { //영역의 왼쪽 끝 인덱스 i에 대해 26 | 27 | if (i > 0) { //영역을 벗어나게 되는 원소 제외 28 | sum -= data[i - 1]; 29 | } 30 | 31 | //새로 영역에 들어온 원소 추가 32 | sum = sum + data[i + k - 1]; 33 | 34 | if (sum % 2 == 0) { 35 | winCount += 1; 36 | 37 | //승리 가능한 지 여부만 중요하므로 탈출 38 | break; 39 | } 40 | } 41 | 42 | if (winCount > 0) { 43 | return true; 44 | } else { 45 | return false; 46 | } 47 | } 48 | 49 | int main() { 50 | int n, k; 51 | int *data; 52 | 53 | scanf("%d %d", &n, &k); 54 | data = new int[n]; 55 | for (int i = 0; i < n; i++) { 56 | scanf("%d", &data[i]); 57 | } 58 | 59 | bool result = isWinnable(data, n, k); 60 | 61 | if (result) { 62 | printf("YES"); 63 | } else { 64 | printf("NO"); 65 | } 66 | 67 | delete[] data; 68 | return 0; 69 | } -------------------------------------------------------------------------------- /chapter02/problem_j/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | def is_winnable(data: List[int], k: int) -> bool: 5 | """ 6 | 게임의 규칙에 따라 현무가 승리할 수 있는 경우의 수가 존재하는지 검사하는 함수 7 | :param data: 정수 배열 8 | :param k: 한 번에 선택할 종이컵의 수 9 | :return: 현무가 승리할 수 있는 경우의 수가 하나 이상 존재한다면 True, 아니면 False 10 | """ 11 | win_count = 0 12 | sum = 0 13 | 14 | # 첫 (k-1)개의 원소에 대한 합을 계산한다. 15 | for i in range(k - 1): 16 | sum += data[i] 17 | 18 | for i in range(n - k + 1): 19 | # 영역의 왼쪽 끝 인덱스 i에 대해 20 | if i > 0: 21 | # 영역을 벗어나게 되는 원소 제외 22 | sum -= data[i - 1] 23 | # 새로 영역에 들어온 원소 추가 24 | sum += data[i + k - 1] 25 | 26 | if sum % 2 == 0: 27 | # 승리 가능한 지 여부만 중요하므로 탈출 28 | win_count += 1 29 | break 30 | 31 | return win_count > 0 # 승리할 수 있는 경우의수가 하나라도 존재한다면 승리 가능하다 32 | 33 | 34 | if __name__ == "__main__": 35 | n, k = [int(w) for w in input().split()] 36 | data = [int(w) for w in input().split()] 37 | print(f"{'YES' if is_winnable(data, k) else 'NO'}") 38 | -------------------------------------------------------------------------------- /chapter03/problem_a/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn stdinln_i32() -> i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn stdinln_vec_i32() -> Vec { 11 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 12 | let mut buffer = String::new(); 13 | std::io::stdin().read_line(&mut buffer).expect("Failed to read line"); 14 | let ret: Vec = buffer.split(" ") 15 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 16 | .collect(); 17 | ret 18 | } 19 | 20 | struct TelBox { 21 | data: Vec, 22 | nr_tel: usize, 23 | cntbox: [u32; 10000], // 컴파일 시간내에 사이즈가 결정되는 어레이, Vector보다 빠르다 24 | } 25 | 26 | impl TelBox { 27 | fn new_from_vec_i32(inputs: Vec, len: usize) -> TelBox { 28 | TelBox{data:inputs, nr_tel:len, cntbox:[0; 10000]} 29 | } 30 | 31 | fn get_most(&mut self) -> u32 { 32 | // TelBox::get_most() 를 완성해주세요! 33 | for i in 0..self.nr_tel { 34 | self.cntbox[self.data[i] as usize] += 1; 35 | } 36 | let mut biggest = 0; 37 | for i in 1..10000 { 38 | if self.cntbox[i] > self.cntbox[biggest] { 39 | biggest = i; 40 | }else if self.cntbox[i] == self.cntbox[biggest] { 41 | if i < biggest { 42 | biggest = i; 43 | } 44 | } 45 | } 46 | biggest as u32 47 | // End of TelBox::get_most() 48 | } 49 | } 50 | 51 | // Rust에서는 array사용시 컴파일시간내에서만 결정되어야한다. 52 | // 이 문제같은 경우 0~10000이라는 조건이 컴파일 시간이전에 결정된다. 53 | // 따라서 이 문제는 Vector가 아닌 Array를 사용한다. 54 | // 힌트 : https://doc.rust-lang.org/std/primitive.array.html 55 | 56 | fn main() { 57 | let nr_tel = stdinln_i32() as usize; 58 | let mut tels: Vec = Vec::new(); 59 | for i in 0..nr_tel { 60 | tels.push(stdinln_i32()); 61 | } 62 | let mut problem = TelBox::new_from_vec_i32(tels, nr_tel); 63 | // TelBox::get_most()를 완성해주세요! 64 | println!("{:04}", problem.get_most()); 65 | } -------------------------------------------------------------------------------- /chapter03/problem_a/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int MAX_TABLE_LENGTH = 10000; 6 | 7 | /** 8 | * data[0] ~ data[n-1]에 등장한 번호들에 대한 빈도수 테이블을 채우는 함수 9 | * @param data 10 | * @param n 11 | * @param table table[x] := data배열에서 x가 등장한 횟수 12 | */ 13 | void fillFrequencyTable(int data[], int n, int table[]) { 14 | for (int i = 0; i < MAX_TABLE_LENGTH; ++i) { 15 | table[i] = 0; 16 | } 17 | for (int i = 0; i < n; ++i) { 18 | int number = data[i]; 19 | table[number] += 1; 20 | } 21 | } 22 | 23 | /** 24 | * data[0] ~ data[n-1]사이에서 가장 많이 등장한 번호를 반환하는 함수 25 | * @param data 26 | * @param n 27 | * @return 가장 많이 등장한 번호. 여러개인 경우 사전순으로 가장 빠른 번호. 28 | */ 29 | int getFrequentNumber(int data[], int n) { 30 | // 0000~9999 중에서 가장 많이 등장한 번호를 구해보자 31 | int frequent_number = 0; 32 | 33 | int table[MAX_TABLE_LENGTH]; // 초기화 에 유의 34 | fillFrequencyTable(data, n, table); 35 | 36 | 37 | for (int i = 0; i < MAX_TABLE_LENGTH; ++i) { 38 | if (table[i] > table[frequent_number]) { 39 | frequent_number = i; 40 | } 41 | } 42 | 43 | return frequent_number; 44 | } 45 | 46 | int main() { 47 | int n; 48 | 49 | scanf("%d", &n); 50 | int *data = new int[n]; 51 | 52 | for (int i = 0; i < n; ++i) { 53 | scanf("%d", &data[i]); 54 | } 55 | 56 | int answer = getFrequentNumber(data, n); 57 | 58 | // 네 자리로 출력 59 | printf("%04d", answer); 60 | 61 | delete[] data; 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /chapter03/problem_a/solution.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const input = (()=>{ 3 | const stdin = fs.readFileSync('/dev/stdin').toString().split('\n'); 4 | let ln=0; 5 | return ()=>stdin[ln++]; 6 | })(); 7 | 8 | // data 입력 및 배열 정렬 9 | const n = Number(input()); 10 | const data = [] 11 | for(let i = 0 ; i < n ; i++){ 12 | data[i] = Number(input()); 13 | } 14 | data.sort() 15 | 16 | // 전화번호 빈도수 table 선언, 초기화 17 | const table = Array(10000).fill(0) 18 | 19 | for(let i = 0 ; i < n ; i++){ 20 | table[data[i]] += 1; 21 | } 22 | 23 | const max = Math.max(...table); 24 | 25 | let answer = String(table.findIndex((x)=> x === max)) 26 | 27 | //자릿수 맞추기 28 | while(answer.length < 4){ 29 | answer = ["0"].concat(num.split("")).join("") 30 | } 31 | 32 | console.log(answer) -------------------------------------------------------------------------------- /chapter03/problem_a/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | def get_most_frequent_number(numbers: List[str]) -> str: 5 | """ 6 | 가장 많이 등장한 뒷자리를 반환하는 함수 7 | :param numbers: 전화번호 목록 8 | :return: 가장 많이 등장한 뒷자리 9 | """ 10 | n = len(numbers) 11 | cnt = [0] * 10000 # cnt[XXXX] := 뒷 자리가 XXXX인 전화번호의 수 12 | for i in range(n): 13 | num = int(numbers[i]) 14 | cnt[num] += 1 15 | 16 | max_index = 0 # 가장 많이 등장한 뒷자리 후보 17 | for num in range(10000): # 모든 뒷자리에 대하여 18 | if cnt[num] > cnt[max_index]: 19 | max_index = num 20 | 21 | return f"{max_index:04d}" 22 | 23 | 24 | if __name__ == '__main__': 25 | n = int(input()) 26 | numbers = [input().strip() for i in range(n)] 27 | print(get_most_frequent_number(numbers)) 28 | -------------------------------------------------------------------------------- /chapter03/problem_b/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List, Tuple 2 | 3 | 4 | def get_most_least_colors(n: int, paints: List[Tuple[int, int, int]]) -> Tuple[int, int]: 5 | """ 6 | 가장 많이 등장한 뒷자리를 반환하는 함수 7 | :param n: 좌석의 개수 8 | prints: 좌석의 색상을 변경하는 명령어들의 리스트 9 | :return: (가장 많이 사용된 색상, 가장 적게 사용된 색상) 10 | """ 11 | m = len(paints) 12 | 13 | min_color = -1 14 | max_color = -1 15 | 16 | seats = [0] * n 17 | 18 | for left, right, color in paints: 19 | for i in range(left, right + 1): 20 | seats[i - 1] = color 21 | 22 | min_color = max_color = seats[0] 23 | 24 | freq = [0] * 100 25 | for color in seats: 26 | freq[color] += 1 27 | 28 | for color in range(0, 100): 29 | if freq[color] == 0: continue 30 | if freq[color] > freq[max_color]: 31 | max_color = color 32 | if freq[color] < freq[min_color]: 33 | min_color = color 34 | 35 | return max_color, min_color 36 | 37 | 38 | if __name__ == '__main__': 39 | n, m = [int(i) for i in input().split()] 40 | paints = [[int(i) for i in input().split()] for j in range(m)] 41 | max_color, min_color = get_most_least_colors(n, paints) 42 | print(max_color) 43 | print(min_color) 44 | -------------------------------------------------------------------------------- /chapter03/problem_c/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | def fill_frequency_table(data: List[int], length=100000) -> List[int]: 5 | table = [0] * (length + 1) 6 | for number in data: 7 | table[number] += 1 8 | return table 9 | 10 | 11 | def all_unqiue_elements(numbers: List[int]) -> List[int]: 12 | """ 13 | 모든 유일한 원소를 반환하는 함수 14 | :param numbers: 입력 값 15 | :return: 모든 유일한 원소를 반환 16 | """ 17 | n = len(numbers) 18 | table = fill_frequency_table(numbers) 19 | unique_elements = [] 20 | for number in range(1, 100001): 21 | if table[number] == 1: 22 | unique_elements.append(number) 23 | return unique_elements 24 | 25 | def all_unqiue_elements_by_sort(numbers: List[int]) -> List[int]: 26 | """ 27 | 정렬을 활용한 풀ㅣ 28 | """ 29 | n = len(numbers) 30 | uniques = [] 31 | numbers.sort() 32 | for i in range(n): 33 | if (i == 0 or numbers[i] != numbers[i-1]) and (i == n-1 or numbers[i] != numbers[i+1]): 34 | uniques.append(numbers[i]) 35 | return uniques 36 | 37 | 38 | if __name__ == "__main__": 39 | n = int(input()) 40 | numbers = [int(x) for x in input().split()] 41 | uniques = all_unqiue_elements(numbers) 42 | print(' '.join([str(x) for x in uniques])) 43 | -------------------------------------------------------------------------------- /chapter03/problem_d/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | public static final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); 9 | 10 | public static final int MAX_N = 1000000; 11 | public static int[] FIBONACCI_TABLE; 12 | 13 | /** 14 | * 피보나치 수열의 1~n번째 항을 배열에 저장하여 반환해주는 함수 15 | * * 단, 항의 가장 뒤 8자리만을 저장한다. 16 | * @param n 17 | * @return fibo[i] := 피보나치 수열의 i번째 항 18 | */ 19 | public static int[] makeFibonacciTable(int n) 20 | { 21 | int[] fibo = new int[n+1]; 22 | fibo[1] = 0; 23 | fibo[2] = 1; 24 | for(int i = 3; i <= n; i+= 1) 25 | { 26 | fibo[i] = (fibo[i-1] + fibo[i-2]) % 100000000; 27 | } 28 | return fibo; 29 | } 30 | 31 | /** 32 | * 피보나치 수열의 n번째 항을 반환하는 함수 33 | * 단, 항의 가장 뒤 8자리만을 반환한다. 34 | * @param n 35 | * @return 36 | */ 37 | public static int getFibo(int n) 38 | { 39 | int answer = 0; 40 | 41 | answer = FIBONACCI_TABLE[n]; 42 | 43 | return answer; 44 | } 45 | 46 | public static void main(String[] args) throws Exception { 47 | 48 | //가능한 모든 범위에 대한 피보나치 수열의 값을 계산해두자 49 | FIBONACCI_TABLE = makeFibonacciTable(MAX_N); 50 | 51 | //테스트케이스를 반복 수행한다. 52 | int caseSize = scanner.nextInt(); 53 | for (int caseIndex = 1; caseIndex <= caseSize; caseIndex += 1) 54 | { 55 | int n = scanner.nextInt(); 56 | 57 | //피보나치 수열의 n번째 항을 계산하여 출력한다. 58 | int answer = getFibo(n); 59 | writer.write(String.valueOf(answer) + "\n"); 60 | } 61 | 62 | //불필요한 배열은 가능하면 할당 해제해주는 버릇을 들이자. 63 | FIBONACCI_TABLE = null; 64 | 65 | writer.flush(); 66 | writer.close(); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /chapter03/problem_d/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn stdinln_i32() -> i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin().read_line(&mut buffer).expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | struct LimitedFibo { 11 | series: Vec, 12 | nr_case: usize, 13 | cases: Vec, 14 | } 15 | 16 | impl LimitedFibo { 17 | fn new_from_cases(inputs: Vec, len: usize) -> LimitedFibo { 18 | // 피보나치 수열을 만들기 위해서 첫번째, 두번째 값을 미리 넣어줘야한다. 19 | let initial_series = vec![0, 1]; 20 | LimitedFibo {series: initial_series, nr_case: len, cases: inputs} 21 | } 22 | 23 | fn calculation(&mut self) { 24 | // LimitedFibo::calculation() 을 완성해주세요. 25 | // 사용자가 요구하는 피보나치(8자 한정)을 self.cases vector에 넣어줍시다. 26 | // 1번째 피보나치 값은 series[0]에 들어가며 100번째는 [99]에 들어갑니다. 27 | let max_order = match self.cases.iter().max() { 28 | Some(max) => (*max - 1) as usize, 29 | None => 0 as usize, 30 | }; 31 | // 구름IDE가 구버젼인 관계로 0 .. =max_order 사용 불가능 32 | let start = self.series.len(); 33 | for i in start..max_order+1 { 34 | let val = (self.series[i-1] + self.series[i-2]) % 100000000; 35 | self.series.push(val); 36 | } 37 | // end of LimitedFibo::calculation() 38 | } 39 | 40 | fn show_result(self) { 41 | for iidx in self.cases { 42 | let uidx = (iidx-1) as usize; 43 | let temp = { 44 | // 응시자가 해당 번호에대해서 만들지 않았다면 -1출력. 45 | if uidx >= self.series.len() { 46 | -1 as i32 47 | }else { 48 | self.series[uidx] 49 | } 50 | }; 51 | println!("{}", temp); 52 | } 53 | } 54 | } 55 | 56 | fn main() { 57 | let nr_case = stdinln_i32() as usize; 58 | let mut inputs: Vec = Vec::new(); 59 | for _i in 0..nr_case { 60 | inputs.push(stdinln_i32()); 61 | } 62 | let mut problem = LimitedFibo::new_from_cases(inputs, nr_case); 63 | // LimitedFibo::calculation() 을 완성해주세요! 64 | problem.calculation(); 65 | problem.show_result(); 66 | } -------------------------------------------------------------------------------- /chapter03/problem_d/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | 7 | const int MAX_N = 1000000; 8 | vector FIBONACCI_TABLE; 9 | 10 | /** 11 | * 피보나치 수열의 1~n번째 항을 배열에 저장하여 반환해주는 함수 12 | * * 단, 항의 가장 뒤 8자리만을 저장한다. 13 | * @param n 14 | * @return fibo[i] := 피보나치 수열의 i번째 항 15 | */ 16 | vector makeFibonacciTable(int n) { 17 | const int MOD = 100000000; 18 | 19 | // 피보나치 배열을 미리 선언해준다. 20 | vector ret(n + 1); 21 | ret[1] = 0; // 첫 번재 항은 0이다. 22 | ret[2] = 1; // 두 번째 항은 1이다. 23 | 24 | // 세 번째 항부터는 피보다치의 정의를 이용해 계산을 한다. 25 | // f(n) = f(n - 1) + f(n - 2) 26 | for (int i = 3; i <= n; ++i) { 27 | ret[i] = ret[i - 1] + ret[i - 2]; 28 | 29 | // 피보나치를 구할 때 모듈러 값을 이용해 뒤에 8자리만 남기도록 해 준다. 30 | // ((A % MOD) + (B % MOD)) % MOD == (A + B) % MOD 31 | // 위 식이 성립하기 때문에 피보나치의 값이 잘못될 일은 없다. 32 | ret[i] %= MOD; 33 | } 34 | 35 | return ret; 36 | } 37 | 38 | /** 39 | * 피보나치 수열의 n번째 항을 반환하는 함수 40 | * 단, 항의 가장 뒤 8자리만을 반환한다. 41 | * @param n 42 | * @return 43 | */ 44 | int getFibo(int n) { 45 | // 피보나치의 값을 미리 계산해 뒀기 때문에 그 값을 반환한다. 46 | // 첫 번째 항의 인덱스가 0이므로 -1을 해 준다. 47 | int answer = FIBONACCI_TABLE[n]; 48 | return answer; 49 | } 50 | 51 | int main() { 52 | FIBONACCI_TABLE = makeFibonacciTable(MAX_N); 53 | 54 | int caseSize; 55 | scanf("%d", &caseSize); 56 | 57 | for (int caseIndex = 1; caseIndex <= caseSize; ++caseIndex) { 58 | int n; 59 | scanf("%d", &n); 60 | 61 | // 피보나치 수열의 n번째 항을 계산하여 출력한다. 62 | int answer = getFibo(n); 63 | printf("%d\n", answer); 64 | } 65 | 66 | // 불필요한 배열은 가능하면 할당 해제해주는 버릇을 들이자. 67 | FIBONACCI_TABLE.clear(); 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /chapter03/problem_d/solution.py: -------------------------------------------------------------------------------- 1 | MOD = 100_000_000 2 | 3 | fib_cache = None # 전역 캐시 배열로 활용해보자 4 | 5 | 6 | def fib(n: int) -> int: 7 | """ 8 | 피보나치 수열을 구하는 함수 9 | :param n: 10 | :return: 피보나치 수열의 n번째 항을 MOD로 나눈 나머지 11 | """ 12 | global fib_cache 13 | global MOD 14 | 15 | if fib_cache is None: 16 | fib_cache = [0, 1] 17 | for i in range(2, 1_000_001): 18 | fib_cache.append((fib_cache[i - 1] + fib_cache[i - 2]) % MOD) 19 | 20 | return fib_cache[n] 21 | 22 | 23 | if __name__ == '__main__': 24 | case_num = int(input()) 25 | for _ in range(case_num): 26 | n = int(input()) 27 | fib_n = fib(n) 28 | print(fib_n) 29 | -------------------------------------------------------------------------------- /chapter03/problem_e/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class Paper { 7 | public: 8 | int leftColumn; //가장 왼쪽 격자의 열 번호 9 | int rightColumn; //가장 오른쪽 격자의 열 번호 10 | int topRow; //가장 위쪽 격자의 행 번호 11 | int bottomRow; //가장 아래쪽 격자의 행 번호 12 | 13 | Paper(int xPos, int yPos) { 14 | this->leftColumn = xPos; 15 | this->rightColumn = this->leftColumn + 9; 16 | this->bottomRow = yPos; 17 | this->topRow = this->bottomRow + 9; 18 | } 19 | }; 20 | 21 | /** 22 | * 색종이들이 덮고 있는 영역의 총 넓이를 계산하는 함수 23 | * 24 | * @param papers 25 | * @param n 26 | * @return 27 | */ 28 | int getCoveredArea(const vector &papers, int n) { 29 | int answer = 0; //색종이들이 덮은 영역의 총 넓이 30 | 31 | // 도화지의 모든 격자에 대하여 32 | // board[r][c] := 격자를 덮은 색종이의 갯수 33 | vector < vector > board(100, vector(100, 0)); 34 | 35 | for (int i = 0; i < n; ++i) { // 모든 색종이 p에 대하여 36 | const Paper &p = papers[i]; 37 | for (int row = p.bottomRow; row <= p.topRow; row += 1) { 38 | for (int col = p.leftColumn; col <= p.rightColumn; col += 1) { 39 | //이 색종이가 덮은 모든 위치 에 대하여 40 | //한번씩 board[row][col]의 값을 1 증가시킨다. 41 | board[row][col] += 1; 42 | } 43 | } 44 | } 45 | 46 | //도화지에 존재하는 모든 격자에 대하여 47 | for (int row = 0; row < 100; row += 1) { 48 | for (int col = 0; col < 100; col += 1) { 49 | if (board[row][col] > 0) { //한 개 이상의 색종이가 덮은 격자의 수를 계산한다 50 | answer += 1; 51 | } 52 | } 53 | } 54 | 55 | //각 격자의 넓이는 1이므로, 56 | //격자의 수가 곧 넓이가 된다. 57 | return answer; 58 | } 59 | 60 | int main() { 61 | int caseSize; 62 | scanf("%d", &caseSize); 63 | 64 | for (int caseIndex = 1; caseIndex <= caseSize; ++caseIndex) { 65 | int n; 66 | scanf("%d", &n); 67 | 68 | vector papers; 69 | for (int i = 0; i < n; ++i) { 70 | int leftX, bottomY; 71 | scanf("%d%d", &leftX, &bottomY); 72 | papers.push_back(Paper(leftX, bottomY)); 73 | } 74 | 75 | int answer = getCoveredArea(papers, n); 76 | 77 | printf("%d\n", answer); 78 | } 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /chapter03/problem_e/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List, Tuple 2 | 3 | 4 | def get_covered_area(points: List[Tuple[int, int]]) -> int: 5 | """ 6 | 100x100 도화지에서 색종이들이 차지하는 면적을 구하는 함수 7 | :param points: 각 색종이의 왼쪽 아래 좌표 8 | :return: 색종이들이 차지하는 면적 9 | """ 10 | n = len(points) 11 | answer = 0 12 | 13 | paper = [[0] * 100 for _ in range(100)] 14 | for x, y in points: 15 | for i in range(x, x + 10): 16 | for j in range(y, y + 10): 17 | paper[i][j] += 1 18 | 19 | for x in range(100): 20 | for y in range(100): 21 | if paper[x][y] > 0: 22 | answer += 1 23 | 24 | return answer 25 | 26 | 27 | if __name__ == '__main__': 28 | case_num = int(input()) 29 | for _ in range(case_num): 30 | n = int(input()) 31 | points = [(int(x) for x in input().split()) for _ in range(n)] 32 | print(get_covered_area(points)) 33 | -------------------------------------------------------------------------------- /chapter03/problem_f/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class Range { 7 | public: 8 | int index; 9 | int left; 10 | int right; 11 | long long totalPoint; 12 | 13 | Range(int index, int left, int right) { 14 | this->index = index; 15 | this->left = left; 16 | this->right = right; 17 | this->totalPoint = 0; 18 | } 19 | }; 20 | 21 | /** 22 | * 23 | * @param n 카드의 수 24 | * @param m 앨범을 구매한 팬의 수 25 | * @param cards 각 카드에 적힌 숫자의 리스트 (cards[1] ~ card[n]) 26 | * @param ranges 각 팬이 선택한 범위의 리스트 (ranges[0] ~ ranges[m-1]) 27 | * @return 총 점수의 합이 가장 큰 범위 객체 28 | */ 29 | Range getBestRange(int n, int m, const vector &cards, const vector &ranges) { 30 | Range answer = ranges[0]; 31 | 32 | 33 | // 누적 합 배열을 계산한다 34 | // psum[i] := cards[1] ~ cards[i]의 합 35 | vector rangeSum(n + 1, 0); 36 | for (int i = 1; i <= n; ++i) { 37 | rangeSum[i] = rangeSum[i - 1] + cards[i]; 38 | } 39 | 40 | for (int i = 0; i < m; ++i) { // 모든 범위 정보 r에 대하여 41 | Range range = ranges[i]; 42 | 43 | // 해당 범위의 누적합을 계산한다 44 | range.totalPoint = rangeSum[range.right] - rangeSum[range.left - 1]; 45 | 46 | // 현재까지 구한 가장 큰 누적합보다 더 크다면 갱신한다 47 | if (answer.totalPoint < range.totalPoint) { 48 | answer = range; 49 | } 50 | } 51 | 52 | return answer; 53 | } 54 | 55 | int main() { 56 | int n, m; 57 | scanf("%d%d", &n, &m); 58 | vector cards(n + 1); 59 | vector ranges; 60 | 61 | // 각 카드의 정보를 입력받는다. 62 | for (int i = 1; i <= n; ++i) { 63 | scanf("%d", &cards[i]); 64 | } 65 | 66 | // 팬들의 정보를 입력받는다. 67 | for (int i = 1; i <= m; ++i) { 68 | int l, r; 69 | scanf("%d%d", &l, &r); 70 | ranges.push_back(Range(i, l, r)); 71 | } 72 | 73 | // 범위의 합이 가장 큰 범위를 계산한다. 74 | Range answer = getBestRange(n, m, cards, ranges); 75 | 76 | printf("%d %lld\n", answer.index, answer.totalPoint); 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /chapter03/problem_f/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List, Tuple 2 | 3 | 4 | def get_maximum_range_sum(cards: List[int], ranges: List[Tuple[int, int]]) -> int: 5 | """ 6 | 카드들의 리스트와 구간들의 리스트가 주어질 때, 구간들의 구간합 중 최댓값을 반환합니다. 7 | :param cards: list of cards 8 | :param ranges: list of ranges 9 | :return: maximum range sum 10 | """ 11 | max_sum = None 12 | max_index = None 13 | 14 | n = len(cards) 15 | m = len(ranges) 16 | rangesum_cache = [] # 구간합 캐시 배열로 활용해보세요 17 | 18 | rangesum_cache.append(0) 19 | 20 | for c in cards: 21 | rangesum_cache.append(c + rangesum_cache[-1]) 22 | 23 | for i in range(m): 24 | start, end = ranges[i] 25 | sum = rangesum_cache[end] - rangesum_cache[start - 1] 26 | if max_sum is None or max_sum < sum: 27 | max_sum = sum 28 | max_index = i + 1 29 | 30 | return max_index, max_sum 31 | 32 | 33 | if __name__ == '__main__': 34 | n, m = [int(x) for x in input().split()] 35 | cards = [int(x) for x in input().split()] 36 | ranges = [tuple(int(x) for x in input().split()) for _ in range(m)] 37 | max_index, max_sum = get_maximum_range_sum(cards, ranges) 38 | print(f"{max_index} {max_sum}") 39 | -------------------------------------------------------------------------------- /chapter03/problem_g/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class frequency_table: 5 | """ 6 | 생년월일의 빈도수를 저장하는 클래스 7 | """ 8 | num_uniques: int # 현재 저장된 생년월일 중 유일한 생년월일의 수 9 | table: List[int] # table[i] = 생년월일이 i인 사람의 수 10 | 11 | def __init__(self, table_length=1_000000): 12 | self.num_uniques = 0 13 | self.table = [0] * 1000000 14 | 15 | def add_birthdate(self, birthdate: int): 16 | count = self.table[birthdate] 17 | if count == 0: 18 | self.num_uniques += 1 19 | elif count == 1: 20 | self.num_uniques -= 1 21 | self.table[birthdate] += 1 22 | 23 | def remove_birthdate(self, birthdate: int): 24 | count = self.table[birthdate] 25 | if count == 1: 26 | self.num_uniques -= 1 27 | elif count == 2: 28 | self.num_uniques += 1 29 | self.table[birthdate] -= 1 30 | 31 | 32 | def get_number_of_exclusive_ranges(birthdates: List[int], m: int) -> int: 33 | """ 34 | 모든 원소가 서로 다른 m개의 연속된 구간의 수를 반환하는 함수 35 | :param birthdates: 생년월일 리스트 36 | :param m: 구간의 길이 37 | :return: 모든 원소가 서로 다른 m개의 연속된 구간의 수 38 | """ 39 | n = len(birthdates) 40 | table = frequency_table() 41 | answer = 0 42 | for i in range(m): 43 | table.add_birthdate(birthdates[i]) 44 | 45 | if table.num_uniques == m: answer += 1 46 | 47 | for i in range(m, len(birthdates)): 48 | table.add_birthdate(birthdates[i]) 49 | table.remove_birthdate(birthdates[i - m]) 50 | if table.num_uniques == m: answer += 1 51 | 52 | return answer 53 | 54 | 55 | if __name__ == '__main__': 56 | n, m = [int(x) for x in input().split()] 57 | birthdates = [int(x) for x in input().split()] 58 | answer = get_number_of_exclusive_ranges(birthdates, m) 59 | print(answer) 60 | -------------------------------------------------------------------------------- /chapter03/problem_h/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | /** 10 | * 중복을 포함해 두 카드의 합으로 만들 수 있는 당첨번호의 수를 계산하는 함수 11 | * @param n 카드의 수 12 | * @param m 검사하려는 당첨번호의 수 13 | * @param cards 각 카드에 적힌 숫자들 14 | * @param target 검사하려는 각 당첨번호 리스트 15 | * @return 16 | */ 17 | public static int getPossibleTargetNumber(int n, int m, int[] cards, int[] target) 18 | { 19 | int answer = 0; //만들 수 있는 당첨번호의 수 20 | 21 | Arrays.sort(cards); 22 | 23 | for(int k : target) 24 | { // 모든 타겟 k에 대하여 25 | 26 | boolean possible = false; // 두 수의 합으로 만들 수 있는지 여부 27 | 28 | for(int x : cards) 29 | { // 모든 카드 중 하나인 x에 대하여 30 | 31 | // x와 k가 상수이므로 y를 계산할 수 있다. 32 | int y = k - x; 33 | 34 | if(Arrays.binarySearch(cards, y) >= 0 ) 35 | { //배열에 y가 존재한다 <==> x+y=k가 되는 가 존재한다. 36 | //이를 표시하고 나간다. 37 | possible = true; 38 | break; 39 | } 40 | } 41 | 42 | if(possible) 43 | { // z가 두 수의 조합으로 표현될 수 있다면, 44 | // 가능한 숫자의 갯수를 증가시킨다. 45 | answer += 1; 46 | } 47 | } 48 | 49 | return answer; 50 | } 51 | 52 | public static void main(String[] args) throws Exception { 53 | int n = scanner.nextInt(); // 카드의 수 54 | int m = scanner.nextInt(); // 검사 할 후보 당첨번호의 수 55 | 56 | int[] cards = new int[n]; 57 | int[] targets = new int[m]; 58 | 59 | // 각 카드 정보를 입력받는다 60 | for(int i = 0 ; i < n ; i ++) 61 | { 62 | cards[i] = scanner.nextInt(); 63 | } 64 | 65 | // 각 당첨번호를 입력받는다 66 | for(int i = 0 ; i < m ; i ++) 67 | { 68 | targets[i] = scanner.nextInt(); 69 | } 70 | 71 | int answer = getPossibleTargetNumber(n, m, cards, targets); 72 | 73 | System.out.println(answer); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /chapter03/problem_h/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | /** 8 | * 중복을 포함해 두 카드의 합으로 만들 수 있는 당첨번호의 수를 계산하는 함수 9 | * @param n 카드의 수 10 | * @param m 검사하려는 당첨번호의 수 11 | * @param cards 각 카드에 적힌 숫자들 12 | * @param target 검사하려는 각 당첨번호 리스트 13 | * @return 14 | */ 15 | int getPossibleTargetNumber(int n, int m, int *cards, int *targets) { 16 | int answer = 0; //만들 수 있는 당첨번호의 수 17 | 18 | // 모든 카드를 오름차순으로 정렬한다 19 | sort(cards, cards + n); 20 | 21 | for (int i = 0; i < m; ++i) { 22 | int k = targets[i]; // 모든 타겟 k에 대하여 23 | bool possible = false; 24 | 25 | for (int j = 0; j < n; ++j) { 26 | int x = cards[j]; // 모든 카드 중 하나인 x에 대하여 27 | 28 | // x와 k가 상수이므로 y를 계산할 수 있다. 29 | int y = k - x; 30 | 31 | if (binary_search(cards, cards + n, y) == true) { 32 | //배열에 y가 존재한다 <==> x+y=k가 되는 가 존재한다. 33 | //이를 표시하고 나간다. 34 | possible = true; 35 | break; 36 | } 37 | } 38 | 39 | if (possible) { // z가 두 수의 조합으로 표현될 수 있다면, 40 | // 가능한 숫자의 갯수를 증가시킨다. 41 | answer += 1; 42 | } 43 | } 44 | 45 | return answer; 46 | } 47 | 48 | int main() { 49 | int n; // 카드의 수 50 | int m; // 검사 할 후보 당첨번호의 수 51 | scanf("%d %d", &n, &m); 52 | 53 | int *cards = new int[n]; 54 | int *targets = new int[m]; 55 | 56 | // 각 카드 정보를 입력받는다 57 | for (int i = 0; i < n; i++) { 58 | scanf("%d", &cards[i]); 59 | } 60 | 61 | // 각 후보 당첨번호를 입력받는다 62 | for (int i = 0; i < m; i++) { 63 | scanf("%d", &targets[i]); 64 | } 65 | 66 | int answer = getPossibleTargetNumber(n, m, cards, targets); 67 | 68 | printf("%d\n", answer); 69 | 70 | 71 | delete[] cards; 72 | delete[] targets; 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /chapter03/problem_k/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | class ArrayUtil { 6 | 7 | /** 8 | * 두 오름차순 배열 A와 B를 하나로 합쳐 재정렬하는 함수 9 | * 10 | * @param A 배열 1 11 | * @param N 배열 1의 길이 12 | * @param B 배열 2 13 | * @param M 배열 2의 길이 14 | * @return 두 배열을 합쳐 정렬한 결과를 반환한다 15 | */ 16 | public static int[] mergerTwoSortedArray(int[] A, int N, int[] B, int M) { 17 | int[] C = new int[N + M]; 18 | 19 | int i = 0; // 배열 A의 반복자 20 | int j = 0; // 배열 B의 반복자 21 | int k = 0; // 배열 C의 반복자 22 | 23 | // 두 배열 모두 원소가 남아있다면 24 | while (i < N && j < M) { 25 | // 두 배열의 A[i]와 B[j]중 더 작은 값을 C[k]에 저장한다. 26 | // 이후 i 혹은 j와 k를 증가시켜준다. 27 | if (A[i] < B[j]) { 28 | C[k++] = A[i++]; 29 | } else { 30 | C[k++] = B[j++]; 31 | } 32 | } 33 | 34 | // A 배열에 원소가 남아있다면 C의 뒷 부분에 차례로 쌓는다 35 | while (i < N) { 36 | C[k++] = A[i++]; 37 | } 38 | 39 | // B 배열에 원소가 남아있다면 C의 뒷 부분에 차례로 쌓는다 40 | while (j < M) { 41 | C[k++] = B[j++]; 42 | } 43 | 44 | return C; 45 | } 46 | } 47 | 48 | public class Main { 49 | public static final Scanner scanner = new Scanner(System.in); 50 | 51 | 52 | public static void main(String[] args) throws Exception { 53 | int N = scanner.nextInt(); 54 | int M = scanner.nextInt(); 55 | 56 | int[] A = new int[N]; 57 | int[] B = new int[M]; 58 | 59 | for (int i = 0; i < N; i += 1) { 60 | A[i] = scanner.nextInt(); 61 | } 62 | for (int j = 0; j < M; j += 1) { 63 | B[j] = scanner.nextInt(); 64 | } 65 | 66 | int[] mergedArray = ArrayUtil.mergerTwoSortedArray(A, N, B, M); 67 | 68 | StringBuilder builder = new StringBuilder(); 69 | 70 | for (int i = 0; i < mergedArray.length; i += 1) { 71 | if (i > 0) { 72 | builder.append(' '); 73 | } 74 | 75 | builder.append(mergedArray[i]); 76 | } 77 | 78 | System.out.println(builder.toString()); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /chapter03/problem_k/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | vector mergeArray(int n, int m, vector&arrayA, vector&arrayB) { 6 | int idxA = 0; 7 | int idxB = 0; 8 | vectoranswer; 9 | 10 | while (idxA < n && idxB < m) { 11 | if (arrayA[idxA] < arrayB[idxB]) { 12 | answer.push_back(arrayA[idxA++]); 13 | } 14 | else { 15 | answer.push_back(arrayB[idxB++]); 16 | } 17 | } 18 | while (idxA < n) { 19 | answer.push_back(arrayA[idxA++]); 20 | } 21 | while (idxB < m) { 22 | answer.push_back(arrayB[idxB++]); 23 | } 24 | return answer; 25 | } 26 | 27 | int main() { 28 | int n, m; 29 | cin >> n >> m; 30 | vectorarrayA(n); 31 | vectorarrayB(m); 32 | for (int i = 0; i < n; i++) { 33 | cin >> arrayA[i]; 34 | } 35 | for (int i = 0; i < m; i++) { 36 | cin >> arrayB[i]; 37 | } 38 | vectormergedArray = mergeArray(n, m, arrayA, arrayB); 39 | for (int i = 0; i < mergedArray.size(); i++) { 40 | if (i > 0) cout << ' '; 41 | cout << mergedArray[i]; 42 | } 43 | cout << endl; 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /chapter04/problem_a/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn stdinln_i32() -> i32 { 4 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 5 | let mut buffer = String::new(); 6 | std::io::stdin() 7 | .read_line(&mut buffer) 8 | .expect("Failed to read stdin."); 9 | buffer.trim().parse::().unwrap() 10 | } 11 | 12 | fn solve(target: i32) -> (i32, i32, i32) { 13 | let x = (target - 1) % 9; 14 | let y = (target - 1) / 9; 15 | let g = (y / 3) * 3 + (x / 3); 16 | (y + 1, x + 1, g + 1) 17 | } 18 | 19 | fn main() { 20 | let mut question_list: Vec = Vec::with_capacity(100); 21 | let nr_case = stdinln_i32() as usize; 22 | 23 | for _ in 0..nr_case { 24 | question_list.push(stdinln_i32()); 25 | } 26 | 27 | for i in 0..nr_case { 28 | let ans = solve(question_list[i]); 29 | println!("Case #{}:", i + 1); 30 | println!("{} {} {}", ans.0, ans.1, ans.2); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /chapter04/problem_a/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | const int MAX_ROW = 9; 6 | const int MAX_COL = 9; 7 | 8 | 9 | class SudokuBoard { 10 | public: 11 | // 칸의 번호로 행의 번호를 계산하는 메소드 12 | int getRowByIndex(int index) { 13 | // 칸의 번호에 대해 마디를 가지고 증가하므로 몫으로 계산할 수 있다. 14 | return (index - 1) / 9 + 1; 15 | } 16 | 17 | // 칸의 번호로 열의 번호를 계산하는 메소드 18 | int getColByIndex(int index) { 19 | // 칸의 번호에 대해 규칙적으로 순환하므로 나머지로 계산할 수 있다. 20 | return (index - 1) % 9 + 1; 21 | } 22 | 23 | // 칸의 번호로 그룹 번호를 계산하는 메소드 24 | int getGroupByIndex(int index) { 25 | int r = getRowByIndex(index); 26 | int c = getColByIndex(index); 27 | return getGroupByPosition(r, c); 28 | } 29 | 30 | // 칸의 위치 (행, 열)로 그룹 번호를 계산하는 메소드 31 | int getGroupByPosition(int row, int column) { 32 | // 행의 번호를 통해, 해당 행에 존재하는 그룹들 중 가장 왼쪽 그룹의 번호를 알 수 있다. 33 | int left = ((row - 1) / 3) * 3 + 1; 34 | // 열의 번호를 통해, 해당 행에 존재하는 그룹들 중 몇 번째 그룹에 속하는지 알 수 있다. 35 | int offset = ((column - 1) / 3); 36 | return left + offset; 37 | } 38 | 39 | // 칸의 위치 (행, 열)로 칸의 번호를 계산하는 메소드 40 | int getIndexByPosition(int row, int column) { 41 | // 행과 열 번호를 알면 반대로 인덱스도 쉽게 계산할 수 있다. 42 | return (row - 1) * 9 + (column - 1) % 9 + 1; 43 | } 44 | }; 45 | 46 | 47 | void process(int caseIndex) { 48 | int index; 49 | scanf("%d", &index); 50 | 51 | SudokuBoard board = SudokuBoard(); 52 | 53 | // 칸의 번호로 행, 열, 그룹 번호를 계산한다 54 | int row = board.getRowByIndex(index); 55 | int col = board.getColByIndex(index); 56 | int group = board.getGroupByIndex(index); 57 | 58 | printf("Case #%d:\n", caseIndex); 59 | printf("%d %d %d\n", row, col, group); 60 | } 61 | 62 | int main() { 63 | int caseSize; 64 | scanf("%d", &caseSize); 65 | 66 | for (int caseIndex = 1; caseIndex <= caseSize; ++caseIndex) { 67 | process(caseIndex); 68 | } 69 | } -------------------------------------------------------------------------------- /chapter04/problem_b/main.rs: -------------------------------------------------------------------------------- 1 | fn stdinln_i32() -> i32 { 2 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 3 | let mut buffer = String::new(); 4 | std::io::stdin() 5 | .read_line(&mut buffer) 6 | .expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn stdinln_vec_i32() -> Vec { 11 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 12 | let mut buffer = String::new(); 13 | std::io::stdin() 14 | .read_line(&mut buffer) 15 | .expect("Failed to read line"); 16 | let ret: Vec = buffer 17 | .split(" ") 18 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 19 | .collect(); 20 | ret 21 | } 22 | 23 | fn main() { 24 | let mut map: [bool; 5000] = [false; 5000]; 25 | let mut result: Vec = Vec::with_capacity(1000); 26 | let case_info = stdinln_vec_i32(); 27 | let len = case_info[0] as usize; 28 | let nr_user = case_info[1] as usize; 29 | 30 | for _ in 0..nr_user { 31 | let input = stdinln_i32() as usize; 32 | let mut idx = input % len; 33 | loop { 34 | if map[idx] { 35 | idx = (idx + 1) % len; 36 | } else { 37 | map[idx] = true; 38 | result.push(idx as i32); 39 | break; 40 | } 41 | } 42 | } 43 | 44 | for i in 0..nr_user { 45 | println!("{}", result[i]); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /chapter04/problem_b/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class TicketTable { 7 | public: 8 | vector used; 9 | int length; 10 | 11 | TicketTable(int length) { 12 | this->length = length; 13 | this->used.assign(length, false); 14 | } 15 | 16 | /** 17 | * 사용자의 회원 번호로 지급받게 될 행운권 번호를 계산하는 메소드 18 | */ 19 | int findEmptyIndexByUserId(int userId) { 20 | int index = userId % length; // 가장 초기에 시도 할 티켓 번호 21 | while (this->isEmpty(index) == true) { // 사용된 티켓 번호라면 건너 뛴다 22 | index = (index + 1) % length; // 다음 번호를 조사해나간다. 23 | } 24 | return index; // 사용되지 않은 인덱스를 찾아서 반환한다 25 | } 26 | 27 | /** 28 | * 해당 행운권 번호가 이미 사용 중인지 여부를 반환하는 메소드 29 | */ 30 | bool isEmpty(int ticketIndex) { 31 | return this->used[ticketIndex]; // 사용여부 <==> used[ticketIndex] 32 | } 33 | 34 | /** 35 | * 티켓 사용 여부를 갱신하기 위한 메소드 36 | */ 37 | void setUsed(int index, bool status) { 38 | this->used[index] = status; 39 | } 40 | }; 41 | 42 | vector getTicketNumbers(int n, int m, const vector &ids) { 43 | vector tickets; 44 | TicketTable table = TicketTable(n); 45 | 46 | for (int i = 0; i < m; i++) { 47 | int userId = ids[i]; 48 | int ticketIndex = table.findEmptyIndexByUserId(userId); 49 | tickets.push_back(ticketIndex); 50 | table.setUsed(ticketIndex, true); 51 | } 52 | 53 | return tickets; 54 | } 55 | 56 | int main() { 57 | // n: 전체 티켓의 수 58 | // m: 요청 고객의 수 59 | int n, m; 60 | scanf("%d%d", &n, &m); 61 | 62 | vector ids(m); 63 | for (int i = 0; i < m; ++i) { 64 | scanf("%d", &ids[i]); 65 | } 66 | 67 | vector tickets = getTicketNumbers(n, m, ids); 68 | for (int i = 0; i < tickets.size(); ++i) { 69 | printf("%d\n", tickets[i]); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /chapter04/problem_c/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | public static void testCase(int caseIndex) { //각 테스트케이스에 대하여 10 | int num1 = scanner.nextInt(); 11 | int num2 = scanner.nextInt(); 12 | 13 | // 두 숫자의 최대 공약수와 최소 공배수를 계산한다 14 | long gcd = MathUtil.getGCD(num1, num2); 15 | long lcm = MathUtil.getLCM(num1, num2); 16 | 17 | // 정답을 출력한다 18 | System.out.printf("Case #%d:\n", caseIndex); 19 | System.out.printf("%d %d\n", gcd, lcm); 20 | } 21 | 22 | public static void main(String[] args) throws Exception { 23 | int caseSize = scanner.nextInt(); 24 | 25 | for (int caseIndex = 1; caseIndex <= caseSize; caseIndex += 1) { 26 | testCase(caseIndex); 27 | } 28 | } 29 | 30 | } 31 | 32 | class MathUtil { 33 | 34 | /** 35 | * a와 b의 최대 공약수를 계산하는 함수 36 | * 37 | * @param a 38 | * @param b 39 | * @return 40 | */ 41 | static long getGCD(long a, long b) { 42 | while (a % b != 0) 43 | { // b가 a의 약수가 아니라면 반복한다 44 | long c = a % b; // 나머지를 계산한다 45 | a = b; // 이후 b와 c에 대해 이 과정을 반복한다 46 | b = c; // a <= b, b <= c 47 | } 48 | // b가 a의 약수라면, b가 a의 최대 공약수다 49 | return b; 50 | } 51 | 52 | /** 53 | * a와 b의 최소 공배수를 계산하는 함수 54 | * 55 | * @param a 56 | * @param b 57 | * @return 58 | */ 59 | static long getLCM(long a, long b) { 60 | // 두 수의 곱에서 최대 공약수를 나누면 최소 공배수다 61 | return a * b / getGCD(a, b); 62 | } 63 | } -------------------------------------------------------------------------------- /chapter04/problem_c/main.rs: -------------------------------------------------------------------------------- 1 | fn stdinln_i32() -> i32 { 2 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 3 | let mut buffer = String::new(); 4 | std::io::stdin() 5 | .read_line(&mut buffer) 6 | .expect("Failed to read stdin."); 7 | buffer.trim().parse::().unwrap() 8 | } 9 | 10 | fn stdinln_vec_i32() -> Vec { 11 | // 이 함수는 하나의 줄을 stdin으로 받아 여러개의 integer 을 vector로 리턴합니다. 12 | let mut buffer = String::new(); 13 | std::io::stdin() 14 | .read_line(&mut buffer) 15 | .expect("Failed to read line"); 16 | let ret: Vec = buffer 17 | .split(" ") 18 | .map(|x| x.trim().parse().expect("Unexpected Integer Pattern")) 19 | .collect(); 20 | ret 21 | } 22 | 23 | fn custom_gcd(a: i32, b: i32) -> i32 { 24 | // Optimized fastest way to get gcd value that 2**N. 25 | let gcd2_log = std::cmp::min(a.trailing_zeros(), b.trailing_zeros()); 26 | let mut x = a >> gcd2_log; 27 | let mut y = b >> gcd2_log; 28 | loop { 29 | let z = x % y; 30 | x = y; 31 | y = z; 32 | if y == 0 { 33 | break; 34 | } 35 | } 36 | x << gcd2_log 37 | } 38 | 39 | fn custom_lcm(a: i32, b: i32, gcd: i32) -> i64 { 40 | (b as i64 / gcd as i64) * a as i64 41 | } 42 | 43 | fn main() { 44 | let mut question: Vec<(i32, i32)> = Vec::with_capacity(100); 45 | let nr_case = stdinln_i32() as usize; 46 | 47 | for _ in 0..nr_case { 48 | let case = stdinln_vec_i32(); 49 | question.push((case[0], case[1])); 50 | } 51 | 52 | for i in 0..nr_case { 53 | let gcd = custom_gcd(question[i].0, question[i].1); 54 | let lcm = custom_lcm(question[i].0, question[i].1, gcd); 55 | 56 | println!("Case #{}:\n{} {}", i + 1, gcd, lcm); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /chapter04/problem_c/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | 6 | /** 7 | * a와 b의 최대 공약수를 계산하는 함수 8 | * 9 | * @param a 10 | * @param b 11 | * @return 12 | */ 13 | long long getGCD(long long a, long long b) { 14 | while (a % b != 0) { // b가 a의 약수가 아니라면 반복한다 15 | long long c = a % b; // 나머지를 계산한다 16 | a = b; // 이후 b와 c에 대해 이 과정을 반복한다 17 | b = c; // a <= b, b <= c 18 | } 19 | // b가 a의 약수라면, b가 a의 최대 공약수다 20 | return b; 21 | } 22 | 23 | /** 24 | * a와 b의 최소 공배수를 계산하는 함수 25 | * 26 | * @param a 27 | * @param b 28 | * @return 29 | */ 30 | long long getLCM(long long a, long long b) { 31 | // 두 수의 곱에서 최대 공약수를 나누면 최소 공배수다 32 | return a * b / getGCD(a, b); 33 | } 34 | 35 | void process(int caseIndex) { 36 | int num1, num2; 37 | scanf("%d%d", &num1, &num2); 38 | 39 | long long gcd = getGCD(num1, num2); 40 | long long lcm = getLCM(num1, num2); 41 | 42 | printf("Case #%d:\n", caseIndex); 43 | printf("%lld %lld\n", gcd, lcm); 44 | } 45 | 46 | int main() { 47 | int caseSize; 48 | scanf("%d", &caseSize); 49 | 50 | for (int caseIndex = 1; caseIndex <= caseSize; ++caseIndex) { 51 | process(caseIndex); 52 | } 53 | } -------------------------------------------------------------------------------- /chapter04/problem_d/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | /** 10 | * 모든 수열이 동시에 최초의 원소를 만나는 최소 주기를 계산하는 함수 11 | * 12 | * @param n 수열의 수 13 | * @param sizes 각 순환 수열의 길이(주기) 14 | * @return 15 | */ 16 | public static long getGlobalPeriod(int n, long[] sizes) { 17 | long globalPeriod = MathUtil.getLCM(sizes); 18 | return globalPeriod; 19 | } 20 | 21 | public static void main(String[] args) throws Exception { 22 | int n = scanner.nextInt(); // 수열의 수 23 | long[] sizes = new long[n]; // 각 수열의 주기 24 | 25 | for (int i = 0; i < n; i++) { 26 | sizes[i] = scanner.nextLong(); 27 | } 28 | 29 | // 전체의 공통 주기만큼 이후에 다시 최초로 만나게 되므로 30 | long answer = 1 + getGlobalPeriod(n, sizes); 31 | 32 | // 정답을 출력한다 33 | System.out.println(answer); 34 | } 35 | 36 | } 37 | 38 | 39 | class MathUtil { 40 | public static long getGCD(long a, long b) { 41 | if (a % b == 0) { 42 | return b; 43 | } 44 | return getGCD(b, a % b); 45 | } 46 | 47 | public static long getLCM(long a, long b) { 48 | return a * b / getGCD(a, b); 49 | } 50 | 51 | /** 52 | * 여러 숫자에 대한 공통 최소 공배수를 계산하는 함수 53 | * 54 | * @param numbers 55 | * @return 56 | */ 57 | public static long getLCM(long[] numbers) { 58 | if (numbers.length == 0) { 59 | return 0; 60 | } 61 | long lcm = numbers[0]; 62 | for (int i = 1; i < numbers.length; i += 1) 63 | { // 모든 숫자 numbers[i]에 대하여 차례로 64 | // lcm := numbers[0] ~ numbers[i-1]에 대한 최대 공약수 65 | lcm = getLCM(lcm, numbers[i]); 66 | // lcm := numbers[0] ~ numbers[i]에 대한 최대 공약수 67 | } 68 | return lcm; 69 | } 70 | } -------------------------------------------------------------------------------- /chapter04/problem_d/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | long long getGCD(long long a, long long b) { 7 | if (a % b == 0) { 8 | return b; 9 | } 10 | return getGCD(b, a % b); 11 | } 12 | 13 | long long getLCM(long a, long b) { 14 | return a * b / getGCD(a, b); 15 | } 16 | 17 | /** 18 | * 여러 숫자에 대한 공통 최소 공배수를 계산하는 함수 19 | * 20 | * @param numbers 21 | * @return 22 | */ 23 | long long getLCM(vector &numbers) { 24 | if (numbers.size() == 0) { 25 | return 0; 26 | } 27 | 28 | long long lcm = numbers[0]; 29 | 30 | for (int i = 1; i < numbers.size(); i += 1) { 31 | // 모든 숫자 numbers[i]에 대하여 차례로 32 | // lcm := numbers[0] ~ numbers[i-1]에 대한 최대 공약수 33 | lcm = getLCM(lcm, numbers[i]); 34 | // lcm := numbers[0] ~ numbers[i]에 대한 최대 공약수 35 | } 36 | 37 | return lcm; 38 | } 39 | 40 | /** 41 | * 모든 수열이 동시에 최초의 원소를 만나는 최소 주기를 계산하는 함수 42 | * 43 | * @param n 수열의 수 44 | * @param sizes 각 순환 수열의 길이(주기) 45 | * @return 46 | */ 47 | long long getGlobalPeriod(vector &sizes) { 48 | long globalPeriod = getLCM(sizes); 49 | return globalPeriod; 50 | } 51 | 52 | int main() { 53 | int n; 54 | scanf("%d", &n); 55 | 56 | vector sizes(n); 57 | 58 | for (int i = 0; i < n; i += 1) { 59 | scanf("%lld", &sizes[i]); 60 | } 61 | 62 | long long answer = 1 + getGlobalPeriod(sizes); 63 | printf("%lld\n", answer); 64 | } 65 | -------------------------------------------------------------------------------- /chapter04/problem_e/Main.java: -------------------------------------------------------------------------------- 1 | 2 | import java.io.*; 3 | import java.lang.*; 4 | import java.util.*; 5 | 6 | 7 | public class Main { 8 | public static final Scanner scanner = new Scanner(System.in); 9 | 10 | public static void testCase(int caseIndex) { 11 | long N = scanner.nextLong(); 12 | 13 | // N을 소인수 분해한다 14 | ArrayList factors = MathUtil.factorize(N); 15 | 16 | // 정답을 출력한다 17 | System.out.printf("#%d:\n", caseIndex); 18 | for(int i = 0 ; i 0 ){ 21 | System.out.print(" "); 22 | } 23 | System.out.print(factors.get(i)); 24 | } 25 | System.out.println(); 26 | } 27 | 28 | public static void main(String[] args) throws Exception { 29 | int caseSize = scanner.nextInt(); 30 | 31 | for (int caseIndex = 1; caseIndex <= caseSize; caseIndex += 1) { 32 | testCase(caseIndex); 33 | } 34 | } 35 | 36 | } 37 | 38 | 39 | class MathUtil{ 40 | /** 41 | * 자연수 N을 구성하는 모든 소인수를 반환하는 함수 42 | * 43 | * @param N 44 | * @return 45 | */ 46 | public static ArrayList factorize(long N) 47 | { 48 | ArrayList factors = new ArrayList<>(); 49 | for(long div = 2; div * div <= N; div += 1) 50 | { // sqrt(N)이하의 자연수 div에 대해서 51 | while(N % div == 0) 52 | { // div이 N의 약수라면? 53 | // 이 때, div보다 작은 약수는 모두 처리되었으므로 div은 소인수임이 보장된다 54 | 55 | // 소인수 목록에 div을 추가한다. 56 | factors.add(div); 57 | 58 | // N에서 div을 소거해준다. 59 | // 그러므로 이후에는 div을 제외한 소인수를 찾게 된다. 60 | N /= div; 61 | } 62 | } 63 | if( N > 1 ) 64 | { // 소인수를 찾지 못하고 남아있는 N이 존재한다면, 소수일 수 밖에 없다. 65 | // 이를 소인수에 추가한다. 66 | factors.add(N); 67 | } 68 | return factors; 69 | } 70 | } -------------------------------------------------------------------------------- /chapter04/problem_e/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use std::io::prelude::*; 3 | 4 | fn stdinln_i32() -> i32 { 5 | // 이 함수는 하나의 줄을 stdin으로 받아 단 하나의 integer를 리턴합니다. 6 | let mut buffer = String::new(); 7 | std::io::stdin() 8 | .read_line(&mut buffer) 9 | .expect("Failed to read stdin."); 10 | buffer.trim().parse::().unwrap() 11 | } 12 | 13 | fn custom_prime(target: i32) -> Vec { 14 | let mut ret: Vec = Vec::new(); 15 | // Optimized fastest way to get prime value that 2**N. 16 | let prime2 = target.trailing_zeros() as usize; 17 | for _ in 0..prime2 { 18 | ret.push(2); 19 | } 20 | // for(long i = 2; i*i <= N && temp != 1;) 21 | let mut factor = 3; 22 | let mut foo = target >> prime2; 23 | 24 | loop { 25 | if foo == 1 { 26 | break; 27 | } else if factor * factor > target { 28 | ret.push(foo); 29 | break; 30 | } 31 | 32 | if foo % factor == 0 { 33 | ret.push(factor); 34 | foo /= factor; 35 | } else { 36 | factor += 2; 37 | } 38 | } 39 | 40 | ret 41 | } 42 | 43 | fn main() { 44 | let nr_nums = stdinln_i32() as usize; 45 | let nums = { 46 | let mut ret: Vec = Vec::with_capacity(nr_nums); 47 | for _ in 0..nr_nums { 48 | ret.push(stdinln_i32()); 49 | } 50 | ret 51 | }; 52 | 53 | for i in 0..nr_nums { 54 | let answer = custom_prime(nums[i]); 55 | println!("#{}:", i + 1); 56 | for item in answer.iter() { 57 | print!("{} ", item); 58 | } 59 | println!(""); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /chapter04/problem_e/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | /** 7 | * 자연수 N을 구성하는 모든 소인수를 반환하는 함수 8 | * 9 | * @param N 10 | * @return 11 | */ 12 | vector factorize(long long n) { 13 | vector factors; 14 | 15 | for (long long div = 2; div * div <= n; div += 1) { // sqrt(N)이하의 자연수 div에 대해서 16 | while (n % div == 0) { 17 | // div이 N의 약수라면? 18 | // 이 때, div보다 작은 약수는 모두 처리되었으므로 div은 소인수임이 보장된다 19 | 20 | // 소인수 목록에 div을 추가한다. 21 | factors.push_back(div); 22 | 23 | // N에서 div을 소거해준다. 24 | // 그러므로 이후에는 div을 제외한 소인수를 찾게 된다. 25 | n /= div; 26 | } 27 | } 28 | if (n > 1) { 29 | // 소인수를 찾지 못하고 남아있는 N이 존재한다면, 소수일 수 밖에 없다. 30 | // 이를 소인수에 추가한다. 31 | factors.push_back(n); 32 | } 33 | 34 | return factors; 35 | } 36 | 37 | void process(int caseIndex) { 38 | long long n; 39 | scanf("%lld", &n); 40 | 41 | vector factors = factorize(n); 42 | 43 | printf("#%d:\n", caseIndex); 44 | for (int i = 0; i < factors.size(); ++i) { 45 | if (i > 0) { 46 | printf(" "); 47 | } 48 | printf("%lld", factors[i]); 49 | } 50 | printf("\n"); 51 | } 52 | 53 | int main() { 54 | int caseSize; 55 | scanf("%d", &caseSize); 56 | 57 | for (int caseIndex = 1; caseIndex <= caseSize; ++caseIndex) { 58 | process(caseIndex); 59 | } 60 | } -------------------------------------------------------------------------------- /chapter04/problem_h/Main.java: -------------------------------------------------------------------------------- 1 | 2 | import java.io.*; 3 | import java.lang.*; 4 | import java.util.*; 5 | 6 | 7 | public class Main { 8 | public static final Scanner scanner = new Scanner(System.in); 9 | 10 | public static void testCase(int caseIndex) { 11 | int M = scanner.nextInt(); 12 | int N = scanner.nextInt(); 13 | int x = scanner.nextInt(); 14 | int y = scanner.nextInt(); 15 | 16 | // <1,1> ~ 연도를 표현하는 카잉 달력을 생성한다 17 | KaingCalendar calendar = new KaingCalendar(M, N); 18 | 19 | // 이 달력에서 가 몇 번째 연도인지 계산한다 20 | int answer = calendar.getIndex(x, y); 21 | 22 | // 정답을 출력한다 23 | System.out.println(answer); 24 | } 25 | 26 | public static void main(String[] args) throws Exception { 27 | int caseSize = scanner.nextInt(); 28 | 29 | for (int caseIndex = 1; caseIndex <= caseSize; caseIndex += 1) { 30 | testCase(caseIndex); 31 | } 32 | } 33 | 34 | } 35 | 36 | class KaingCalendar { 37 | final int M; // 왼쪽 번호의 최대 값 38 | final int N; // 오른쪽 번호의 최대 값 39 | 40 | KaingCalendar(int M, int N) { 41 | this.M = M; 42 | this.N = N; 43 | } 44 | 45 | /** 46 | * 'index'번째 날짜의 X(왼쪽 번호)를 반환하는 함수 47 | * 48 | * @param index 49 | * @return 50 | */ 51 | public int getXbyIndex(int index) 52 | { // M 주기로 단순히 순환하므로 나머지로 계산할 수 있다. 53 | return (index - 1) % M + 1; 54 | } 55 | 56 | /** 57 | * 'index'번째 날짜의 Y(오른쪽 번호)를 반환하는 함수 58 | * 59 | * @param index 60 | * @return 61 | */ 62 | public int getYByIndex(int index) 63 | { // N 주기로 단순히 순환하므로 나머지로 계산할 수 있다. 64 | return (index - 1) % N + 1; 65 | } 66 | 67 | /** 68 | * @param x 69 | * @param y 70 | * @return 이 달력에서 라는 연도가 등장하는 순번 71 | * 등장하지 않는 연도라면 -1을 반환한다 72 | */ 73 | public int getIndex(int x, int y) 74 | { // x번째 날짜는 항상 왼쪽 번호가 x다. 75 | // 그리고 왼쪽 날짜는 M 주기로 항상 x가 등장한다 76 | for (int index = x; index <= M * N; index += M){ 77 | // 왼쪽이 x인 모든 날짜에 대해 78 | if (getYByIndex(index) == y) { 79 | // 오른쪽이 y인 날짜가 존재한다면 반환한다 80 | return index; 81 | } 82 | } 83 | //존재하지 않는다면 -1을 반환한다 84 | return -1; 85 | } 86 | } -------------------------------------------------------------------------------- /chapter04/problem_h/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class KaingCalendar { 4 | public: 5 | int M; // 왼쪽 번호의 최대 값 6 | int N; // 오른쪽 번호의 최대 값 7 | 8 | KaingCalendar(int M, int N) { 9 | this->M = M; 10 | this->N = N; 11 | } 12 | 13 | /** 14 | * 'index'번째 날짜의 X(왼쪽 번호)를 반환하는 함수 15 | * 16 | * @param index 17 | * @return 18 | */ 19 | int getXbyIndex(int index) { 20 | // M 주기로 단순히 순환하므로 나머지로 계산할 수 있다. 21 | return (index - 1) % M + 1; 22 | } 23 | 24 | /** 25 | * 'index'번째 날짜의 Y(오른쪽 번호)를 반환하는 함수 26 | * 27 | * @param index 28 | * @return 29 | */ 30 | int getYByIndex(int index) { 31 | // N 주기로 단순히 순환하므로 나머지로 계산할 수 있다. 32 | return (index - 1) % N + 1; 33 | } 34 | 35 | /** 36 | * 37 | * 38 | * @param x 39 | * @param y 40 | * @return 이 달력에서 라는 연도가 최초로 등장하는 순번 41 | * 등장하지 않는 연도라면 -1을 반환한다 42 | */ 43 | int getIndex(int x, int y) { 44 | // x번째 날짜는 항상 왼쪽 번호가 x다. 45 | // 그리고 왼쪽 날짜는 M 주기로 항상 x가 등장한다 46 | for (int index = x; index <= M * N; index += M) { 47 | // 왼쪽이 x인 모든 날짜에 대해 48 | if (getYByIndex(index) == y) { 49 | // 오른쪽이 y인 날짜가 존재한다면 반환한다 50 | return index; 51 | } 52 | } 53 | //존재하지 않는다면 -1을 반환한다 54 | return -1; 55 | } 56 | }; 57 | 58 | void process(int caseIndex) { 59 | int M, N, x, y; 60 | scanf("%d%d%d%d", &M, &N, &x, &y); 61 | 62 | // <1,1> ~ 연도를 표현하는 카잉 달력을 생성한다 63 | KaingCalendar calendar(M, N); 64 | 65 | // 이 달력에서 가 몇 번째 연도인지 계산한다 66 | int answer = calendar.getIndex(x, y); 67 | 68 | // 정답을 출력한다 69 | printf("%d\n", answer); 70 | } 71 | 72 | int main() { 73 | int caseSize; 74 | scanf("%d", &caseSize); 75 | 76 | for (int caseIndex = 1; caseIndex <= caseSize; ++caseIndex) { 77 | process(caseIndex); 78 | } 79 | } -------------------------------------------------------------------------------- /chapter04/problem_i/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class Sieve { 7 | public: 8 | int maximumValue; 9 | vector isPrime; 10 | vector primes; 11 | 12 | Sieve(int maximumValue) { 13 | this->maximumValue = maximumValue; 14 | this->isPrime.assign(maximumValue + 1, true); 15 | fillSieve(); 16 | } 17 | 18 | 19 | void fillSieve() { 20 | isPrime[0] = isPrime[1] = false; 21 | for (int num = 2; num <= maximumValue; num += 1) { 22 | if (isPrime[num] == false) { 23 | continue; 24 | } 25 | 26 | primes.push_back(num); 27 | for (long long mul = (long long) num * num; mul <= maximumValue; mul += num) { 28 | int index = (int) mul; 29 | isPrime[index] = false; 30 | } 31 | } 32 | } 33 | 34 | bool isPrimeNumber(int num) const { 35 | return isPrime[num]; 36 | } 37 | }; 38 | 39 | void process(int caseIndex, const Sieve &sieve) { 40 | int x; 41 | scanf("%d", &x); 42 | 43 | int a = -1, b = -1; 44 | 45 | // 두 수 p, q에 대해 소수 판별을 빠르게 하기 위해서 46 | // 에라토스테네스의 체를 사용한다. 47 | for (int p = 3; p <= x / 2; p += 2) { 48 | // p 보다 작은 모든 홀수 p에 대하여 49 | int q = x - p; // x = p + q가 되는 q가 결정적으로 정해진다 50 | 51 | // p와 q가 모두 소수라면? 52 | if (sieve.isPrimeNumber(p) && sieve.isPrimeNumber(q)) { // x = p + q가 되는 두 홀수 소수 가 존재한다 53 | a = p; 54 | b = q; 55 | break; 56 | } 57 | } 58 | 59 | printf("Case #%d:\n", caseIndex); 60 | if (a > 0 && b > 0) { 61 | printf("%d = %d + %d\n", x, a, b); 62 | } else { 63 | printf("-1\n"); 64 | } 65 | } 66 | 67 | int main() { 68 | const int MAX_VALUE = 1000000; 69 | Sieve sieve(MAX_VALUE); 70 | 71 | int caseSize; 72 | scanf("%d", &caseSize); 73 | 74 | for (int caseIndex = 1; caseIndex <= caseSize; ++caseIndex) { 75 | process(caseIndex, sieve); 76 | } 77 | } -------------------------------------------------------------------------------- /chapter05/problem_d/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | 9 | class Player { 10 | public: 11 | int index; 12 | 13 | Player(int index = 0) { 14 | this->index = index; 15 | } 16 | }; 17 | 18 | /** 19 | * 조세퍼스 게임을 수행하여 각 플레이어가 제거된 순서를 리스트로 반환하는 함수 20 | * 21 | * @param n 플레이어의 수 22 | * @param m 매 턴마다 건너 뛸 사람의 수 23 | * @param players 좌석에 앉아있는 순서대로 주어지는 플레이어 정보 24 | * @return 25 | */ 26 | vector getDeadPlayersList(int n, int m, const vector &players) { 27 | // 현재 게임에서 제외된 플레이어들의 리스트 28 | vector deadPlayers; 29 | 30 | // 아직 게임에서 제외되지 않는 플레이어들의 리스트 31 | queue playerQueue; 32 | 33 | for (int i = 0; i < n; i += 1) { 34 | playerQueue.push(players[i]); 35 | } 36 | 37 | for (int i = 0; i < n; i++) { 38 | // (m-1)명의 사람을 건너뛴다. 39 | int jump = 1 + (m - 1) % playerQueue.size(); 40 | for (int j = 0; j < jump - 1; j += 1) { 41 | Player p = playerQueue.front(); 42 | playerQueue.pop(); 43 | playerQueue.push(p); 44 | } 45 | 46 | // m번째 사람은 게임에서 제외한다. 47 | Player dead = playerQueue.front(); 48 | playerQueue.pop(); 49 | 50 | // 제외 리스트에 추가한다. 51 | deadPlayers.push_back(dead); 52 | } 53 | 54 | 55 | return deadPlayers; 56 | } 57 | 58 | void testcase(int caseIndex) { 59 | int n, m; 60 | scanf("%d %d", &n, &m); 61 | 62 | vector players; 63 | for (int i = 0; i < n; i++) { 64 | players.push_back(Player(i + 1)); 65 | } 66 | 67 | vector deadPlayers = getDeadPlayersList(n, m, players); 68 | 69 | for (int i = 0; i < n; i++) { 70 | if (i > 0) { 71 | printf(" "); 72 | } 73 | 74 | Player p = deadPlayers[i]; 75 | printf("%d", p.index); 76 | } 77 | printf("\n"); 78 | } 79 | 80 | int main() { 81 | int caseSize; 82 | scanf("%d", &caseSize); 83 | 84 | for (int caseIndex = 1; caseIndex <= caseSize; caseIndex += 1) { 85 | testcase(caseIndex); 86 | } 87 | 88 | return 0; 89 | } 90 | 91 | -------------------------------------------------------------------------------- /chapter05/problem_g/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | class City { 10 | public: 11 | int index; // 도시의 인덱스 12 | int income; // 해당 도시의 소득 13 | 14 | City(int index, int income) { 15 | this->index = index; 16 | this->income = income; 17 | } 18 | 19 | bool operator < (const City& o) const { 20 | return this->income < o.income; 21 | } 22 | bool operator > (const City& o) const { 23 | return this->income > o.income; 24 | } 25 | }; 26 | 27 | int getMaximumRangeDifference(int n, int k, const vector& cities) { 28 | int answer = 0; 29 | 30 | // 소득이 가장 작은 도시부터 pop되는 우선순위 큐 31 | priority_queue, greater> rangeMinimum; 32 | 33 | // 소득이 가장 높은 도시부터 pop되는 우선순위 큐 34 | priority_queue rangeMaximum; 35 | 36 | for (int i = 0; i < k - 1; i++) { 37 | rangeMaximum.push(cities[i]); 38 | rangeMinimum.push(cities[i]); 39 | } 40 | for (int i = k - 1; i < n; i++) { 41 | rangeMaximum.push(cities[i]); 42 | rangeMinimum.push(cities[i]); 43 | while (rangeMaximum.top().index < i - k + 1) rangeMaximum.pop(); 44 | while (rangeMinimum.top().index < i - k + 1) rangeMinimum.pop(); 45 | answer = max(answer, rangeMaximum.top().income - rangeMinimum.top().income); 46 | } 47 | 48 | return answer; 49 | } 50 | 51 | void process(int caseIndex) { 52 | int n, k; 53 | cin >> n >> k; 54 | vector cities; 55 | 56 | for (int i = 0; i < n; i += 1) { 57 | int income; 58 | cin >> income; 59 | cities.push_back(City(i, income)); 60 | } 61 | 62 | int answer = getMaximumRangeDifference(n, k, cities); 63 | 64 | cout << answer << endl; 65 | } 66 | 67 | int main() { 68 | int caseSize; 69 | cin >> caseSize; 70 | 71 | for (int caseIndex = 1; caseIndex <= caseSize; caseIndex += 1) { 72 | process(caseIndex); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /chapter05/problem_h/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | public static final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); 9 | 10 | public static void main(String[] args) throws Exception { 11 | int N = scanner.nextInt(); 12 | 13 | TreeSet integers = new TreeSet<>(); 14 | 15 | for(int i = 0 ; i < N ; i++){ 16 | // integers := 이전까지 등장한 모든 정수를 저장한 집합 17 | int X = scanner.nextInt(); 18 | 19 | if(integers.contains(X)){ 20 | // X와 같은 정수가 입력된 적 있다면 21 | writer.write("DUPLICATED\n"); 22 | }else{ 23 | // X와 같은 정수가 입력된 적 없다면 추가한다. 24 | integers.add(X); 25 | writer.write("OK\n"); 26 | } 27 | } 28 | 29 | writer.flush(); 30 | writer.close(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /chapter05/problem_h/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | int n; 6 | scanf("%d", &n); 7 | setintegers; 8 | for (int i = 0; i < n; i++) { 9 | int x; 10 | scanf("%d", &x); 11 | 12 | //C++ set의 find메소드는 찾는 수가 있다면 해당 iterator를, 없다면 end() iterator를 반환한다. 13 | if (integers.find(x) != integers.end()) { //찾는 수가 있다면 14 | printf("DUPLICATED\n"); 15 | } 16 | else { //찾는 수가 없다면 17 | integers.insert(x); //set에 수를 등록한다. 18 | printf("OK\n"); 19 | } 20 | } 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /chapter05/problem_j/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | public static final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); 9 | 10 | public static void main(String[] args) throws Exception { 11 | int N = scanner.nextInt(); 12 | 13 | // 각 <정수, 빈도수> 형태로 key-value를 저장할 Map 자료구조 14 | TreeMap frequencyMap = new TreeMap<>(); 15 | 16 | for(int i = 0 ; i < N; i+= 1){ 17 | // frequencyMap := 이전에 입력된 정수들의 빈도수를 저장하고 있다. 18 | int X = scanner.nextInt(); 19 | 20 | // 한 번도 등장한 적 없는 숫자라면 21 | if(frequencyMap.containsKey(X) == false){ 22 | // 빈도수를 0으로 초기화한다. 23 | frequencyMap.put(X, 0); 24 | } 25 | 26 | // 현재 frequencyMap에 저장된 적 있는 숫자의 갯수를 저장한다. 27 | int c = frequencyMap.size(); 28 | 29 | // X가 등장한 빈도수를 갱신하여 저장한다. 30 | int f = frequencyMap.get(X) + 1; 31 | frequencyMap.put(X, f); 32 | 33 | // 정보를 출력한다. 34 | writer.write(String.format("%d %d\n", c, f)); 35 | 36 | } 37 | 38 | writer.flush(); 39 | writer.close(); 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /chapter05/problem_j/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() { 6 | int n;scanf("%d", &n); 7 | mapM; 8 | for (int i = 1; i <= n; i++) { 9 | int x; scanf("%d", &x); 10 | M[x]++; 11 | printf("%d %d\n", M.size(), M[x]); 12 | } 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /chapter05/problem_k/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | public static final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); 9 | 10 | public static void main(String[] args) throws Exception { 11 | int N = scanner.nextInt(); 12 | 13 | // 한 번 이상 등장한 적 있는 후보들의 이름 14 | ArrayList existingNames = new ArrayList<>(); 15 | 16 | // 각 후보 이름과 득표 수를 저장하는 key-value Map 17 | TreeMap frequencyMap = new TreeMap<>(); 18 | 19 | int maxFrequency = 0; // 가장 많은 득표수 20 | 21 | // 각 후보에 대해 득표수를 가산해나간다. 22 | for (int i = 0; i < N; i += 1) { 23 | String name = scanner.next(); 24 | 25 | if (frequencyMap.containsKey(name) == false) { 26 | existingNames.add(name); 27 | frequencyMap.put(name, 0); 28 | } 29 | 30 | int f = frequencyMap.get(name) + 1; 31 | frequencyMap.put(name, f); 32 | 33 | maxFrequency = Math.max(maxFrequency, f); 34 | } 35 | 36 | // 가장 많은 득표수를 알고 있으므로, 37 | // 모든 후보에 대해 이 득표수를 획득한 후보들을 winnerList에 저장한다. 38 | ArrayList winnersList = new ArrayList<>(); 39 | for (int i = 0; i < existingNames.size(); i += 1) { 40 | String name = existingNames.get(i); 41 | if (frequencyMap.get(name) == maxFrequency) { 42 | winnersList.add(name); 43 | } 44 | } 45 | 46 | // 최대 득표수를 출력한다 47 | writer.write(String.format("%d\n", maxFrequency)); 48 | 49 | // 최대 득표를한 동점 후보들 이름을 사전순으로 출력한다. 50 | Collections.sort(winnersList); 51 | for (int i = 0; i < winnersList.size(); i += 1) { 52 | if (i > 0) { 53 | writer.write(" "); 54 | } 55 | String name = winnersList.get(i); 56 | writer.write(name); 57 | } 58 | 59 | writer.flush(); 60 | writer.close(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /chapter05/problem_k/Source.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # UTF-8 encoding when using korean 3 | 4 | N = int(input()) 5 | 6 | candidates = {} 7 | for i in range(N): 8 | name = input() 9 | if name not in candidates: 10 | candidates[name] = 0 11 | 12 | candidates[name] += 1 13 | 14 | maxPoint = 0 15 | winners = [] 16 | 17 | for name, point in candidates.items(): 18 | if point > maxPoint: 19 | maxPoint = point 20 | winners = [] 21 | 22 | if point == maxPoint: 23 | winners.append(name) 24 | 25 | winners.sort() 26 | 27 | print(maxPoint) 28 | print(' '.join(winners)) 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /chapter05/problem_k/data/gen.py: -------------------------------------------------------------------------------- 1 | import random 2 | import math 3 | import string 4 | 5 | def testcase(tidx, level, n, name_cnt): 6 | names = [ ''.join(random.choices(string.ascii_uppercase, k=10)) for _ in range(name_cnt)] 7 | cnt = dict() 8 | max_cnt = 0 9 | 10 | with open("input.%02d.txt" % tidx, "w") as f: 11 | f.write("%d\n" % n) 12 | for i in range(n): 13 | name = random.choice(names) 14 | if name not in cnt: 15 | cnt[name] = 0 16 | cnt[name] = cnt[name] + 1 17 | max_cnt = max(max_cnt, cnt[name]) 18 | f.write("%s\n" % name ) 19 | 20 | cand = [] 21 | for k, v in cnt.items(): 22 | if v == max_cnt : 23 | cand.append(k) 24 | 25 | cand.sort() 26 | 27 | with open("output.%02d.txt" % tidx, "w") as f: 28 | f.write("%d\n" % (max_cnt)) 29 | f.write("%s" % (' '.join(cand))) 30 | 31 | for tidx in range(2, 51): 32 | level = 1 + (tidx-1)//5 # 1 ~ 10 33 | n = 10 * (level ** 4) 34 | name_cnt = [1, 2 , 3 , 4 , 5 , int(math.sqrt(n)), n//4, n//3, n//2, n][tidx%10] 35 | testcase(tidx, level, n, name_cnt) 36 | 37 | -------------------------------------------------------------------------------- /chapter05/problem_k/data/input.01.txt: -------------------------------------------------------------------------------- 1 | 5 2 | DO 3 | DO 4 | HI 5 | HI 6 | BYE -------------------------------------------------------------------------------- /chapter05/problem_k/data/input.02.txt: -------------------------------------------------------------------------------- 1 | 10 2 | ZSWDFCSHWV 3 | BNWOTHOWMS 4 | BNWOTHOWMS 5 | BNWOTHOWMS 6 | BNWOTHOWMS 7 | OTNCCCTKGM 8 | BNWOTHOWMS 9 | BNWOTHOWMS 10 | ZSWDFCSHWV 11 | ZSWDFCSHWV 12 | -------------------------------------------------------------------------------- /chapter05/problem_k/data/input.03.txt: -------------------------------------------------------------------------------- 1 | 10 2 | KEUDDPWMHS 3 | WZOMYZUCUS 4 | KEUDDPWMHS 5 | OPLRXMBGEE 6 | OPLRXMBGEE 7 | OPLRXMBGEE 8 | FTEYJOSFAK 9 | WZOMYZUCUS 10 | OPLRXMBGEE 11 | OPLRXMBGEE 12 | -------------------------------------------------------------------------------- /chapter05/problem_k/data/input.04.txt: -------------------------------------------------------------------------------- 1 | 10 2 | KOSSPKMVJT 3 | ZNLKTZGKTA 4 | SPCLQLVRAH 5 | KOSSPKMVJT 6 | SPCLQLVRAH 7 | QGWOKFZHNN 8 | SPCLQLVRAH 9 | KFMXYNHDYD 10 | ZNLKTZGKTA 11 | KFMXYNHDYD 12 | -------------------------------------------------------------------------------- /chapter05/problem_k/data/input.05.txt: -------------------------------------------------------------------------------- 1 | 10 2 | GPVRAATADO 3 | DLGMUYXLSR 4 | DLGMUYXLSR 5 | GPVRAATADO 6 | GPVRAATADO 7 | GPVRAATADO 8 | GPVRAATADO 9 | QWKHWIDOVY 10 | GPVRAATADO 11 | QWKHWIDOVY 12 | -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.01.txt: -------------------------------------------------------------------------------- 1 | 2 2 | DO HI -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.02.txt: -------------------------------------------------------------------------------- 1 | 6 2 | BNWOTHOWMS -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.03.txt: -------------------------------------------------------------------------------- 1 | 5 2 | OPLRXMBGEE -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.04.txt: -------------------------------------------------------------------------------- 1 | 3 2 | SPCLQLVRAH -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.05.txt: -------------------------------------------------------------------------------- 1 | 6 2 | GPVRAATADO -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.06.txt: -------------------------------------------------------------------------------- 1 | 8 2 | OHMJQRVMEQ SVRKEFFWKN -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.07.txt: -------------------------------------------------------------------------------- 1 | 7 2 | FTVYQCLPWU KPQAADEMWA -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.08.txt: -------------------------------------------------------------------------------- 1 | 6 2 | DQJBSHGKFK -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.09.txt: -------------------------------------------------------------------------------- 1 | 5 2 | KFTYUFNTXW -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.10.txt: -------------------------------------------------------------------------------- 1 | 160 2 | QRMURNXEVL -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.11.txt: -------------------------------------------------------------------------------- 1 | 406 2 | VPLLZIJPYT -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.12.txt: -------------------------------------------------------------------------------- 1 | 293 2 | FMJPJSJJKU -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.13.txt: -------------------------------------------------------------------------------- 1 | 214 2 | AUZATCDTMR -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.14.txt: -------------------------------------------------------------------------------- 1 | 176 2 | JVYNGTXPWD -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.15.txt: -------------------------------------------------------------------------------- 1 | 36 2 | LYKPDSEUDG ZCBOWCSGDY -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.16.txt: -------------------------------------------------------------------------------- 1 | 11 2 | BIQOQTRRPL CPYNIIEJXF -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.17.txt: -------------------------------------------------------------------------------- 1 | 11 2 | EVDYTSVJTF -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.18.txt: -------------------------------------------------------------------------------- 1 | 8 2 | AWSDIEUOOX -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.19.txt: -------------------------------------------------------------------------------- 1 | 7 2 | VSPMCDCANT -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.20.txt: -------------------------------------------------------------------------------- 1 | 2560 2 | MLBVLEOKIB -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.21.txt: -------------------------------------------------------------------------------- 1 | 3185 2 | KFJIXIKDJU -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.22.txt: -------------------------------------------------------------------------------- 1 | 2110 2 | KXCNLTNIJE -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.23.txt: -------------------------------------------------------------------------------- 1 | 1615 2 | RAEUFVIRIG -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.24.txt: -------------------------------------------------------------------------------- 1 | 1293 2 | HRYVXKBHFX -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.25.txt: -------------------------------------------------------------------------------- 1 | 102 2 | UVLUIZOVUW -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.26.txt: -------------------------------------------------------------------------------- 1 | 12 2 | DFGPYTDPJP FTIDMOBXZF TDFMGZRAEK -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.27.txt: -------------------------------------------------------------------------------- 1 | 14 2 | MLCAEUDGUM -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.28.txt: -------------------------------------------------------------------------------- 1 | 10 2 | ZJUZNOWIJG -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.29.txt: -------------------------------------------------------------------------------- 1 | 6 2 | ISZDZRUNII LIYZJNQYBX XTWDYSJPIN -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.30.txt: -------------------------------------------------------------------------------- 1 | 12960 2 | HAYMFJSNQU -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.31.txt: -------------------------------------------------------------------------------- 1 | 12211 2 | ABCGJKWOYF -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.32.txt: -------------------------------------------------------------------------------- 1 | 8067 2 | YNDMAOMCYK -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.33.txt: -------------------------------------------------------------------------------- 1 | 6095 2 | JHPHQFTMOO -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.34.txt: -------------------------------------------------------------------------------- 1 | 4853 2 | WBHJDWSFAA -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.35.txt: -------------------------------------------------------------------------------- 1 | 187 2 | LVHIDXFSWE -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.36.txt: -------------------------------------------------------------------------------- 1 | 14 2 | HMKEBZBHRP LEXLULYONP -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.37.txt: -------------------------------------------------------------------------------- 1 | 12 2 | UWHNSLJYQK -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.38.txt: -------------------------------------------------------------------------------- 1 | 9 2 | ATJLFHICVT PJBAISSMMS QMZAOQZOTJ SSZZVADCSC -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.39.txt: -------------------------------------------------------------------------------- 1 | 8 2 | JHPRACPJDZ -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.40.txt: -------------------------------------------------------------------------------- 1 | 40960 2 | TYPSQAUWRJ -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.41.txt: -------------------------------------------------------------------------------- 1 | 32874 2 | WYJZSQXCLZ -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.42.txt: -------------------------------------------------------------------------------- 1 | 22076 2 | HZRQZLNAGE -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.43.txt: -------------------------------------------------------------------------------- 1 | 16504 2 | SFKWJREPOU -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.44.txt: -------------------------------------------------------------------------------- 1 | 13246 2 | QTRDUUDHEY -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.45.txt: -------------------------------------------------------------------------------- 1 | 298 2 | ROSUFBKJIH -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.46.txt: -------------------------------------------------------------------------------- 1 | 15 2 | CSJVXAGGPB FVGTDBLGDL -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.47.txt: -------------------------------------------------------------------------------- 1 | 12 2 | EAHWAWQKYG PDNXRMJAAB WJDSNOOYHC -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.48.txt: -------------------------------------------------------------------------------- 1 | 10 2 | DVOGOYVRPG QAHGSEACWD -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.49.txt: -------------------------------------------------------------------------------- 1 | 8 2 | ALUTDSGRTT AYJVXFHWSS -------------------------------------------------------------------------------- /chapter05/problem_k/data/output.50.txt: -------------------------------------------------------------------------------- 1 | 100000 2 | DZBEJTTXQY -------------------------------------------------------------------------------- /chapter05/problem_k/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | int main() { 10 | int N; 11 | cin >> N; 12 | // 현재까지 최다득표한 후보들의 목록 13 | vector curMaxFreqName; 14 | 15 | // 각 후보 이름과 득표 수를 저장하는 key-value Map 16 | map frequencyMap; 17 | 18 | int maxFrequency = 0; // 가장 많은 득표수 19 | 20 | //각이름이하나추가될때마다 현재까지의 최다 특표 값 갱신, 최다 득표 후보 리스트를 갱신해간다. 21 | //vector의 clear메소드는 O(1)이다. 22 | for (int i = 0; i> st; 25 | frequencyMap[st]++; 26 | int k = frequencyMap[st]; 27 | if (k>maxFrequency) { 28 | maxFrequency = k; 29 | curMaxFreqName.clear(); 30 | curMaxFreqName.push_back(st); 31 | } 32 | else if (k == maxFrequency) { 33 | curMaxFreqName.push_back(st); 34 | } 35 | } 36 | 37 | // 최대 득표 후보 수를 출력한다. 38 | cout << maxFrequency << endl; 39 | 40 | // 최대 득표를한 동점 후보들 이름을 사전순으로 출력한다. 41 | sort(curMaxFreqName.begin(), curMaxFreqName.end()); 42 | bool first = true; 43 | for (auto i : curMaxFreqName) { 44 | if(first == false){ 45 | cout << ' '; 46 | } 47 | first = false; 48 | cout << i; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /chapter05/problem_n/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | template 8 | class MidianQueue { 9 | private: 10 | priority_queuemaxQ; 11 | priority_queue, greater>minQ; 12 | 13 | void balancing() { 14 | while (minQ.size() > maxQ.size()) { 15 | maxQ.push(minQ.top()); 16 | minQ.pop(); 17 | } 18 | while (minQ.size() + 1 < maxQ.size()) { 19 | minQ.push(maxQ.top()); 20 | maxQ.pop(); 21 | } 22 | } 23 | public: 24 | size_t size() { 25 | return maxQ.size() + minQ.size(); 26 | } 27 | bool empty() { 28 | return size() == 0; 29 | } 30 | void push(T value) { 31 | if (maxQ.empty() == false && maxQ.top() >= value) { 32 | maxQ.push(value); 33 | } 34 | else { 35 | minQ.push(value); 36 | } 37 | balancing(); 38 | } 39 | void pop() { 40 | maxQ.pop(); 41 | balancing(); 42 | } 43 | T findMidVal() { 44 | T retVal = maxQ.top(); 45 | return retVal; 46 | } 47 | }; 48 | 49 | int main() { 50 | int n; scanf("%d", &n); 51 | MidianQueuequeue; 52 | for (int i = 0; i < n; i++) { 53 | char c; scanf(" %c", &c); 54 | if (c == 'I') { 55 | int x; scanf("%d", &x); 56 | queue.push(x); 57 | printf("%d\n", queue.findMidVal()); 58 | } 59 | else if (c == 'P') { 60 | if (queue.empty() == false) { 61 | queue.pop(); 62 | } 63 | if (queue.empty() == false) { 64 | printf("%d\n", queue.findMidVal()); 65 | } 66 | else { 67 | printf("ERROR\n"); 68 | } 69 | } 70 | else if (c == 'S') { 71 | printf("%d\n", queue.size()); 72 | } 73 | } 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /chapter06/problem_a/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | import java.lang.*; 4 | 5 | class Main { 6 | public static final Scanner scanner = new Scanner(System.in); 7 | /** 8 | * N번째 피보나치 수열의 원소를 출력하는 함수 9 | * 1, 2번째 숫자는 1이고, 다른 원소는 이전의 두 원소의 합이다 10 | */ 11 | public static int fib(int n){ 12 | if(n == 1 || n == 2) return 1; // 1혹은 2일때는 1로 자명하다 13 | else return fib(n-1) + fib(n-2); // 3이상일 때 에는 앞선 두 항의 합을 재귀적으로 반환한다 14 | } 15 | 16 | public static void main(String[] args) throws Exception { 17 | int n = scanner.nextInt(); 18 | int result = fib(n); 19 | System.out.println(result); 20 | } 21 | } -------------------------------------------------------------------------------- /chapter06/problem_b/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.lang.*; 3 | 4 | public class Main { 5 | public static final Scanner scanner = new Scanner(System.in); 6 | 7 | 8 | 9 | /** 10 | * @brief 시작 기둥(from)으로부터 목적지 기둥(to)까지 num개의 원반을 모두 옮기는 최소 이동 횟수를 계산하는 함수 11 | * 12 | * 13 | * @param num 현재 시작 기둥(from)에 놓여져 있는 원반의 수 14 | * @param from num개의 원반들이 꽂혀있는 기둥 15 | * @param buffer 비어있는 기둥 16 | * @param to 원반들을 모두 옮길 기둥 17 | * @return 모든 원반을 옮길 수 있는 최소 이동 횟수 18 | */ 19 | public static int getMinimumMove(int num, Bar from, Bar buffer, Bar to) { 20 | if (num == 0) { 21 | // 원판이 없다면 당연히 아무 이동도 필요하지 않다 22 | return 0; 23 | }else if(num == 1){ 24 | // 원판이 하나 뿐이라면 그냥 이동하면 된다 25 | Disk d = from.stack.pop(); 26 | to.stack.push(d); 27 | // System.out.println(from.name + " -> " + to.name); 28 | return 1; 29 | } 30 | 31 | int move = 0; 32 | 33 | // 현재 가장 아래의 원판을 제외하고 모두 buffer 기둥으로 옮긴다 34 | move += getMinimumMove(num - 1, from, to, buffer); 35 | 36 | // 가장 아래의 원판을 목적지 기둥으로 옮긴다 37 | move += getMinimumMove(1, from, buffer, to); 38 | 39 | // 아까 옮겨두었던 N-1개의 원판들을 이제 차례로 목적지 기둥에 쌓는다 40 | move += getMinimumMove(num - 1, buffer, from, to); 41 | 42 | return move; 43 | } 44 | 45 | 46 | 47 | public static void main(String[] args) throws Exception { 48 | int N = scanner.nextInt(); 49 | 50 | Bar A = new Bar("A"); 51 | Bar B = new Bar("B"); 52 | Bar C = new Bar("C"); 53 | 54 | // 첫 번째 기둥에 N개의 원판을 쌓는다 55 | for (int i = N; i >= 1; i -= 1) { 56 | Disk d = new Disk(i); 57 | A.stack.push(d); 58 | } 59 | 60 | int answer = getMinimumMove(N, A, B, C); 61 | 62 | System.out.println(answer); 63 | } 64 | } 65 | 66 | class Bar{ 67 | String name; 68 | Stack stack; 69 | Bar(String name){ 70 | this.name = name; 71 | this.stack = new Stack<>(); 72 | } 73 | } 74 | 75 | class Disk { 76 | final int size; 77 | 78 | public Disk(int size) { 79 | this.size = size; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /chapter06/problem_b/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class Disk 7 | { 8 | public: 9 | int size; 10 | 11 | Disk(int size) 12 | { 13 | this->size = size; 14 | } 15 | }; 16 | 17 | /** 18 | * @brief 시작 기둥(from)으로부터 목적지 기둥(to)까지 num개의 원반을 모두 옮기는 최소 이동 횟수를 계산하는 함수 19 | * 20 | * 21 | * @param num 현재 시작 기둥(from)에 놓여져 있는 원반의 수 22 | * @param from num개의 원반들이 꽂혀있는 기둥 23 | * @param buffer 비어있는 기둥 24 | * @param to 원반들을 모두 옮길 기둥 25 | * @return 모든 원반을 옮길 수 있는 최소 이동 횟수 26 | */ 27 | int getMinimumMove(int num, stack &from, stack &buffer, stack &to) 28 | { 29 | if (num == 0) 30 | { 31 | // 원판이 없다면 당연히 아무 이동도 필요하지 않다 32 | return 0; 33 | } 34 | else if (num == 1) 35 | { 36 | // 원판이 하나 뿐이라면 그냥 이동하면 된다 37 | Disk d = from.top(); 38 | from.pop(); 39 | to.push(d); 40 | return 1; 41 | } 42 | 43 | int move = 0; 44 | 45 | // 현재 가장 아래의 원판을 제외하고 모두 buffer 기둥으로 옮긴다 46 | move += getMinimumMove(num - 1, from, to, buffer); 47 | 48 | // 가장 아래의 원판을 목적지 기둥으로 옮긴다 49 | move += getMinimumMove(1, from, buffer, to); 50 | 51 | // 아까 옮겨두었던 N-1개의 원판들을 이제 차례로 목적지 기둥에 쌓는다 52 | move += getMinimumMove(num - 1, buffer, from, to); 53 | 54 | return move; 55 | } 56 | 57 | int main() 58 | { 59 | int N; 60 | scanf("%d", &N); 61 | 62 | stack A; 63 | stack B; 64 | stack C; 65 | 66 | // 첫 번째 기둥에 N개의 원판을 쌓는다 67 | for (int i = N; i >= 1; i -= 1) 68 | { 69 | Disk d(i); 70 | A.push(d); 71 | } 72 | 73 | int answer = getMinimumMove(N, A, B, C); 74 | printf("%d\n", answer); 75 | } 76 | -------------------------------------------------------------------------------- /chapter06/problem_d/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const char ITEMS[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; 8 | 9 | /** 10 | * @brief depth 번째 이후 알파벳 조합을 탐색하는 함수 11 | * 모든 알파벳이 선택되었다면, 선택 된 알파벳을 모두 출력한다 12 | * 13 | * @param depth 재귀함수의 깊이 (= 선택된 알파벳 수 + 1) 14 | * @param limit 재귀함수의 최대 깊이 제한 15 | * @param selectedIndex 현재까지 선택한 데이터들의 인덱스 16 | */ 17 | void findAllCombinations(int depth, int limit, vector selectedIndex, vector& answer) { 18 | // depth가 제한보다 커진 경우, limit개 만큼의 문자를 모두 선택했다는 뜻이다 19 | if (depth > limit) { 20 | // 선택한 문자들을 차례로 한 줄에 출력한다 21 | 22 | string str; 23 | for (int i = 1; i < depth; i += 1) { 24 | int index = selectedIndex[i - 1]; 25 | char c = ITEMS[index]; 26 | str += c; 27 | } 28 | answer.push_back(str); 29 | 30 | // 이제 종료한다 31 | return; 32 | } 33 | 34 | 35 | // 고려해야 할 가장 첫 알파벳의 인덱스 36 | // 초기값은 0 37 | int minIndex = 0; 38 | 39 | // 현재 이미 앞서 선택해온 알파벳이 있는 경우 40 | if(depth > 1) { 41 | // 그 알파벳보다 사전순으로 뒤에 있는 문자부터만 검사해주도록 42 | // 최소 인덱스를 제한한다 43 | minIndex = selectedIndex[selectedIndex.size() - 1] + 1; 44 | } 45 | 46 | for (int index = minIndex; index < 26; index += 1) { 47 | // 현재 사용할 수 있는 모든 알파벳의 번호 index에 대해 48 | 49 | // 현재 알파벳을 선택 목록 맨 뒤에 추가한다. 50 | selectedIndex.push_back(index); 51 | 52 | // 이후 다음 하위 조합들을 선택해본다 53 | findAllCombinations(depth + 1, limit, selectedIndex, answer); 54 | 55 | // 이번 페이즈에 선택했던 알파벳을 다시 제거해준다 56 | selectedIndex.pop_back(); 57 | } 58 | } 59 | 60 | int main() { 61 | int N; 62 | cin >> N; 63 | 64 | vector answer; 65 | findAllCombinations(1, N, vector(), answer); 66 | 67 | for (int i = 0; i < answer.size(); i += 1) { 68 | cout << answer << endl; 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /chapter06/problem_e/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | class Main { 6 | public static final int MOD = 1000000007; 7 | 8 | /** 9 | * a^n을 계산하는 함수 10 | * 11 | * @param a 12 | * @param n 13 | * @return a^n을 1,000,000,007로 나눈 나머지를 출력한다 14 | */ 15 | public static long pow(long a, long n) { 16 | if (n == 0) return 1; 17 | if (n == 1) return a; 18 | 19 | long ret = pow((a * a) % MOD, n / 2); 20 | if (n % 2 == 1) { 21 | ret *= a; 22 | } 23 | return ret % MOD; 24 | } 25 | 26 | public static void main(String[] args) throws Exception { 27 | Scanner scanner = new Scanner(System.in); 28 | int a = scanner.nextInt(); 29 | int n = scanner.nextInt(); 30 | long answer = pow(a, n); 31 | System.out.println(answer); 32 | } 33 | } -------------------------------------------------------------------------------- /chapter07/problem_c/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | int getLongestPathLength(int current, int goal, int depth, const vector >& adj, vector& visited) { 9 | if(visited[current] == true || current == goal) { 10 | return 0; 11 | } 12 | 13 | int maxLength = 0; 14 | 15 | visited[current] = true; 16 | for (int i = 0; i < adj[current].size(); i += 1) { 17 | int nextNode = adj[current][i]; 18 | 19 | int length = 1 + getLongestPathLength(nextNode, goal, depth + 1, adj, visited); 20 | maxLength = max(maxLength , length); 21 | } 22 | visited[current] = false; 23 | 24 | return maxLength; 25 | } 26 | 27 | /** 28 | * 두 노드 current부터 goal까지의 최장 경로의 길이를 반환하는 함수 29 | * 30 | * @param current 31 | * @param goal 32 | * @param adj 33 | * @return 34 | */ 35 | int getLongestPathLength(int current, int goal, const vector >& adj) { 36 | int N = adj.size(); 37 | 38 | vector visited(N + 1, false); 39 | 40 | return getLongestPathLength(current, goal, 1, adj, visited); 41 | } 42 | 43 | int main() { 44 | int N, M; 45 | scanf("%d%d", &N, &M); 46 | vector > adj(N + 1); 47 | 48 | int origin, dest; 49 | scanf("%d%d", &origin, &dest); 50 | 51 | for(int i = 0 ; i < M; i += 1){ 52 | int u, v; 53 | scanf("%d%d", &u, &v); 54 | adj[u].push_back(v); 55 | adj[v].push_back(u); 56 | } 57 | 58 | int answer = getLongestPathLength(origin, dest, adj); 59 | printf("%d\n", answer); 60 | } 61 | -------------------------------------------------------------------------------- /chapter07/problem_d/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | class State { 8 | public: 9 | int nodeIndex; 10 | int depth; 11 | 12 | State(int nodeIndex, int depth) { 13 | this->nodeIndex = nodeIndex; 14 | this->depth = depth; 15 | } 16 | }; 17 | 18 | /** 19 | * 그래프의 두 노드 org에서 dest로 이동하는 가장 짧은 경로의 길이를 반환하는 함수 20 | * 21 | * @param org 22 | * @param dest 23 | * @param adj 24 | * @return 25 | */ 26 | int getShortestPathLength(int org, int dest, const vector >& adj) { 27 | int N = adj.size(); 28 | 29 | vector visited(N + 1, false); 30 | vector distance(N + 1, -1); 31 | 32 | State initialState(org, 1); 33 | queue bfsQueue; 34 | bfsQueue.push(initialState); 35 | 36 | while (!bfsQueue.empty()) { 37 | State current = bfsQueue.front(); 38 | bfsQueue.pop(); 39 | 40 | if (visited[current.nodeIndex] == true) { 41 | continue; 42 | } 43 | 44 | visited[current.nodeIndex] = true; 45 | distance[current.nodeIndex] = current.depth - 1; 46 | 47 | for (int i = 0; i < adj[current.nodeIndex].size(); i += 1) { 48 | int next = adj[current.nodeIndex][i]; 49 | if (visited[next] == false) { 50 | State nextState(next, current.depth + 1); 51 | bfsQueue.push(nextState); 52 | } 53 | } 54 | } 55 | 56 | return distance[dest]; 57 | } 58 | 59 | int main() { 60 | int N, M, origin, dest; 61 | scanf("%d%d%d%d", &N, &M, &origin, &dest); 62 | 63 | vector > adj(N + 1); 64 | 65 | for (int i = 0; i < M; i += 1) { 66 | int u, v; 67 | scanf("%d%d", &u, &v); 68 | adj[u].push_back(v); 69 | adj[v].push_back(u); 70 | } 71 | 72 | int answer = getShortestPathLength(origin, dest, adj); 73 | printf("%d\n", answer); 74 | } 75 | -------------------------------------------------------------------------------- /chapter07/problem_e/Main.java: -------------------------------------------------------------------------------- 1 | import java.lang.*; 2 | import java.util.*; 3 | 4 | 5 | public class Main { 6 | public static final Scanner scanner = new Scanner(System.in); 7 | public static final int MAXIMUM_VIRUS = 10000; 8 | 9 | public static void testCase(int caseIndex) { 10 | int targetNumber = scanner.nextInt(); 11 | 12 | int[] distance = new int[MAXIMUM_VIRUS + 1]; 13 | boolean[] visited = new boolean[MAXIMUM_VIRUS + 1]; 14 | 15 | State initialState = new State(1, 1); 16 | Queue queue = new LinkedList<>(); 17 | queue.add(initialState); 18 | 19 | while (queue.isEmpty() == false) { 20 | State current = queue.poll(); 21 | 22 | if(current.numberOfVirus > MAXIMUM_VIRUS){ 23 | continue; 24 | }else if (visited[current.numberOfVirus] == true) { 25 | continue; 26 | } 27 | 28 | visited[current.numberOfVirus] = true; 29 | distance[current.numberOfVirus] = current.depth - 1; 30 | 31 | State nextIncrease = new State(current.numberOfVirus * 2, current.depth + 1); 32 | State nextDecrease = new State(current.numberOfVirus / 3, current.depth + 1); 33 | 34 | queue.add(nextIncrease); 35 | queue.add(nextDecrease); 36 | } 37 | 38 | int answer = distance[targetNumber]; 39 | System.out.println(answer); 40 | } 41 | 42 | public static void main(String[] args) throws Exception { 43 | int caseSize = scanner.nextInt(); 44 | 45 | for (int caseIndex = 1; caseIndex <= caseSize; caseIndex += 1) { 46 | testCase(caseIndex); 47 | } 48 | } 49 | 50 | } 51 | 52 | class State { 53 | public final int numberOfVirus; 54 | public final int depth; 55 | 56 | public State(int numberOfVirus, int depth) { 57 | this.numberOfVirus = numberOfVirus; 58 | this.depth = depth; 59 | } 60 | } -------------------------------------------------------------------------------- /chapter07/problem_e/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int MAXIMUM_VIRUS = 10000; 8 | 9 | class State { 10 | public: 11 | int numberOfVirus; 12 | int depth; 13 | 14 | State(int numberOfVirus, int depth) { 15 | this->numberOfVirus = numberOfVirus; 16 | this->depth = depth; 17 | } 18 | }; 19 | 20 | void testCase(int caseIndex) { 21 | int targetNumber; 22 | scanf("%d", &targetNumber); 23 | 24 | vector distance(MAXIMUM_VIRUS + 1, 0); 25 | vector visited(MAXIMUM_VIRUS + 1, false); 26 | 27 | State initialState(1, 1); 28 | queue q; 29 | q.push(initialState); 30 | 31 | while (q.empty() == false) { 32 | State current = q.front(); 33 | q.pop(); 34 | 35 | if(current.numberOfVirus > MAXIMUM_VIRUS) { 36 | continue; 37 | } else if (visited[current.numberOfVirus] == true) { 38 | continue; 39 | } 40 | 41 | visited[current.numberOfVirus] = true; 42 | distance[current.numberOfVirus] = current.depth - 1; 43 | 44 | State nextIncrease(current.numberOfVirus * 2, current.depth + 1); 45 | State nextDecrease(current.numberOfVirus / 3, current.depth + 1); 46 | 47 | q.push(nextIncrease); 48 | q.push(nextDecrease); 49 | } 50 | 51 | int answer = distance[targetNumber]; 52 | printf("%d\n", answer); 53 | } 54 | 55 | int main() { 56 | int caseSize; 57 | scanf("%d", &caseSize); 58 | 59 | for (int caseIndex = 1; caseIndex <= caseSize; caseIndex += 1) { 60 | testCase(caseIndex); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /chapter08/problem_a/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.lang.*; 3 | import java.util.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | public static boolean hasHamiltonPath(Graph graph){ 10 | boolean[] visited = new boolean[graph.V+1]; 11 | for(int originNode = 1; originNode <= graph.V; originNode += 1){ 12 | boolean has = hasHamiltonPath(1, originNode, visited, graph); 13 | if(has){ 14 | return true; 15 | } 16 | } 17 | return false; 18 | } 19 | 20 | public static boolean hasHamiltonPath(int depth, int currentNode, boolean[] visited, Graph graph) { 21 | if(visited[currentNode]){ 22 | return false; 23 | } 24 | visited[currentNode] = true; 25 | 26 | boolean hasPath = false; 27 | if(depth == graph.V){ 28 | hasPath = true; 29 | }else{ 30 | for(int nextNode = 1; nextNode <= graph.V; nextNode += 1) { 31 | hasPath = hasHamiltonPath(depth+1, nextNode, visited, graph); 32 | if(hasPath){ 33 | break; 34 | } 35 | } 36 | } 37 | 38 | visited[currentNode] = false; 39 | 40 | return hasPath; 41 | } 42 | 43 | public static void main(String[] args) throws Exception { 44 | int V = scanner.nextInt(); 45 | int E =scanner.nextInt(); 46 | 47 | Graph graph = new Graph(V); 48 | for(int i = 0 ; i < E ; i += 1){ 49 | int u = scanner.nextInt(); 50 | int v = scanner.nextInt(); 51 | graph.addEdge(u, v); 52 | } 53 | 54 | boolean hasPath = hasHamiltonPath(graph); 55 | 56 | if(hasPath){ 57 | System.out.println("YES"); 58 | }else{ 59 | System.out.println("NO"); 60 | } 61 | } 62 | 63 | } 64 | 65 | 66 | class Graph{ 67 | private boolean[][] adj; 68 | public final int V; 69 | 70 | public Graph(int V){ 71 | this.adj = new boolean[V+1][V+1]; 72 | this.V = V; 73 | } 74 | 75 | public void addEdge(int u, int v){ 76 | adj[u][v] = adj[v][u] = true; 77 | } 78 | 79 | public boolean hasEdge(int u, int v){ 80 | return adj[u][v]; 81 | } 82 | 83 | 84 | } -------------------------------------------------------------------------------- /chapter08/problem_a/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class Graph{ 7 | public: 8 | vector > adj; 9 | int V; 10 | 11 | Graph(int V) { 12 | this->adj = vector >(V + 1, vector(V + 1, false)); 13 | this->V = V; 14 | } 15 | 16 | void addEdge(int u, int v){ 17 | adj[u][v] = adj[v][u] = true; 18 | } 19 | 20 | bool hasEdge(int u, int v){ 21 | return adj[u][v]; 22 | } 23 | }; 24 | 25 | bool hasHamiltonPath(int depth, int currentNode, vector& visited, const Graph& graph) { 26 | if(visited[currentNode]) { 27 | return false; 28 | } 29 | visited[currentNode] = true; 30 | 31 | bool hasPath = false; 32 | if(depth == graph.V) { 33 | hasPath = true; 34 | } else { 35 | for(int nextNode = 1; nextNode <= graph.V; nextNode += 1) { 36 | hasPath = hasHamiltonPath(depth + 1, nextNode, visited, graph); 37 | if(hasPath) { 38 | break; 39 | } 40 | } 41 | } 42 | 43 | visited[currentNode] = false; 44 | 45 | return hasPath; 46 | } 47 | 48 | 49 | bool hasHamiltonPath(const Graph& graph) { 50 | vector visited(graph.V + 1, false); 51 | for(int originNode = 1; originNode <= graph.V; originNode += 1) { 52 | if(hasHamiltonPath(1, originNode, visited, graph)){ 53 | return true; 54 | } 55 | } 56 | return false; 57 | } 58 | 59 | int main() { 60 | int V, E; 61 | scanf("%d%d", &V, &E); 62 | 63 | Graph graph(V); 64 | for(int i = 0 ; i < E ; i += 1){ 65 | int u, v; 66 | scanf("%d%d", &u, &v); 67 | graph.addEdge(u, v); 68 | } 69 | 70 | if(hasHamiltonPath(graph)) { 71 | puts("YES"); 72 | } else { 73 | puts("NO"); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /chapter08/problem_d/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class DisjointSet { 7 | public: 8 | int size; 9 | vector groupBoss; 10 | vector groupSize; 11 | 12 | DisjointSet(int size) { 13 | this->size = size; 14 | this->groupBoss = vector(size + 1); 15 | this->groupSize = vector(size + 1, 1); 16 | for (int nodeIndex = 1; nodeIndex <= size; nodeIndex += 1) { 17 | groupBoss[nodeIndex] = nodeIndex; 18 | } 19 | } 20 | 21 | int getGroupBoss(int u) { 22 | if (groupBoss[u] == u) { 23 | return u; 24 | } else { 25 | groupBoss[u] = getGroupBoss(groupBoss[u]); 26 | return groupBoss[u]; 27 | } 28 | } 29 | 30 | void unionGroup(int u, int v) { 31 | if(isConnected(u, v)) { 32 | return; 33 | } 34 | 35 | int uBoss = getGroupBoss(u); 36 | int vBoss = getGroupBoss(v); 37 | groupSize[uBoss] += groupSize[vBoss]; 38 | groupBoss[vBoss] = uBoss; 39 | } 40 | 41 | bool isConnected(int u, int v) { 42 | int uBoss = getGroupBoss(u); 43 | int vBoss = getGroupBoss(v); 44 | return uBoss == vBoss; 45 | } 46 | 47 | int getNumberOfConnectedNodes(int u) { 48 | int uBoss = getGroupBoss(u); 49 | return this->groupSize[uBoss]; 50 | } 51 | }; 52 | 53 | int main() { 54 | int N, M; 55 | scanf("%d%d", &N, &M); 56 | 57 | DisjointSet disjointSet(N); 58 | 59 | for (int i = 0; i < M; i += 1) { 60 | char command[10]; 61 | int u, v; 62 | scanf("%s%d%d", command, &u, &v); 63 | if (command[0] == 'L') { 64 | disjointSet.unionGroup(u, v); 65 | int groupSize = disjointSet.getNumberOfConnectedNodes(u); 66 | printf("SIZE = %d\n", groupSize); 67 | } else if (command[0] == 'C') { 68 | if (disjointSet.isConnected(u, v) == true) { 69 | puts("Connected"); 70 | } else { 71 | puts("Separated"); 72 | } 73 | } 74 | 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /chapter09/problem_a/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | import java.lang.*; 4 | 5 | public class Main { 6 | 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | public static void main(String[] args) { 10 | int n = scanner.nextInt(); 11 | int[] arr = new int[n]; 12 | for (int i = 0; i < n; i += 1) { 13 | arr[i] = scanner.nextInt(); 14 | } 15 | 16 | LIS lis = new LIS(arr); 17 | int answer = 0; 18 | for (int i = 0; i < n; i += 1) { 19 | answer = Math.max(answer, lis.f(i)); 20 | } 21 | 22 | System.out.println(answer); 23 | } 24 | } 25 | 26 | class LIS { 27 | private static final int EMPTY = -1; 28 | 29 | private int[] memo; // DP 상태공간 30 | private int[] array; // 수열의 원소 31 | private int n; // 수열의 길이 32 | 33 | public LIS(int[] array) { 34 | this.array = array.clone(); 35 | this.n = array.length; 36 | this.memo = new int[n]; 37 | Arrays.fill(memo, EMPTY); 38 | } 39 | 40 | /** 41 | * array[lastIndex]가 마지막 원소인 모든 LIS 길이를 계산하는 함수 42 | * 43 | * @param lastIndex 부분 수열의 마지막 원소의 인덱스 44 | * @return array[lastIndex]가 마지막 원소인 LIS의 길이 45 | */ 46 | public int f(int lastIndex) { 47 | if (lastIndex < 0) { 48 | // 예외인 경우는 길이 0으로 취급한다. 49 | return 0; 50 | } else if (memo[lastIndex] != EMPTY) { 51 | // 이미 계산된 적 있는 결과라면 반환한다. 52 | return memo[lastIndex]; 53 | } else if (lastIndex == 0) { 54 | return 1; 55 | } 56 | 57 | int answer = 1; 58 | for (int previousIndex = 0; previousIndex < lastIndex; previousIndex += 1) { 59 | int newLength = f(previousIndex) + 1; 60 | if (array[previousIndex] < array[lastIndex] && newLength > answer) { 61 | answer = newLength; 62 | } 63 | } 64 | memo[lastIndex] = answer; 65 | return memo[lastIndex]; 66 | } 67 | } -------------------------------------------------------------------------------- /chapter09/problem_a/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | class LIS { 9 | public: 10 | vector memo; // DP 상태공간 11 | vector array; // 수열의 원소 12 | int n; // 수열의 길이 13 | 14 | LIS(vector array) { 15 | this->array = array; 16 | this->n = array.size(); 17 | this->memo.assign(n, -1); 18 | } 19 | 20 | /** 21 | * array[lastIndex]가 마지막 원소인 모든 LIS 길이를 계산하는 함수 22 | * 23 | * @param lastIndex 부분 수열의 마지막 원소의 인덱스 24 | * @return array[lastIndex]가 마지막 원소인 LIS의 길이 25 | */ 26 | int f(int lastIndex) { 27 | if (lastIndex < 0) { 28 | // 예외인 경우는 길이 0으로 취급한다. 29 | return 0; 30 | } else if (memo[lastIndex] != -1) { 31 | // 이미 계산된 적 있는 결과라면 반환한다. 32 | return memo[lastIndex]; 33 | } else if (lastIndex == 0) { 34 | return 1; 35 | } 36 | 37 | int answer = 1; 38 | 39 | for (int previousIndex = 0; previousIndex < lastIndex; previousIndex += 1) { 40 | int newLength = this->f(previousIndex) + 1; 41 | if (array[previousIndex] < array[lastIndex] && newLength > answer) { 42 | answer = newLength; 43 | } 44 | } 45 | 46 | memo[lastIndex] = answer; 47 | return memo[lastIndex]; 48 | } 49 | }; 50 | 51 | int main() { 52 | int n; 53 | scanf("%d", &n); 54 | 55 | vector arr(n); 56 | for (int i = 0; i < n; i += 1) { 57 | scanf("%d", &arr[i]); 58 | } 59 | 60 | LIS lis(arr); 61 | int answer = 0; 62 | for (int i = 0; i < n; i += 1) { 63 | answer = max(answer, lis.f(i)); 64 | } 65 | 66 | printf("%d\n", answer); 67 | } 68 | -------------------------------------------------------------------------------- /chapter09/problem_b/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | 11 | class FenceRepairing { 12 | public: 13 | vector memo; // DP 상태공간 14 | vector isBroken; // 각 팬스가 고장났는지의 여부 15 | int n; // 팬스의 길이 16 | 17 | FenceRepairing(string str) { 18 | this->n = str.length(); 19 | this->memo.assign(str.length(), -1); 20 | this->isBroken.resize(str.length()); 21 | for (int i = 0; i < str.length(); i += 1) { 22 | isBroken[i] = str[i] == 'X'; 23 | } 24 | } 25 | 26 | /** 27 | * 0번째 팬스부터 (lastIndex)번째 팬스까지 모두 완벽히 수리하는데 소요되는 최소의 비용 28 | * 29 | * @param lastIndex 수리할 가장 마지막(오른쪽) 팬스의 인덱스 30 | * @return 그 때의 최소 비용 31 | */ 32 | double f(int lastIndex) { 33 | if (lastIndex < 0) { 34 | // 수리할 팬스가 없는 경우 35 | return 0; 36 | } else if (memo[lastIndex] != -1) { 37 | // 이미 계산한 적 있는 경우 38 | return memo[lastIndex]; 39 | } 40 | 41 | // 0번째부터 모두 한 번에 교체하는 경우 42 | double answer = sqrt(lastIndex + 1); 43 | 44 | if (false == isBroken[lastIndex]) { 45 | // lastIndex번째가 고장나지 않은 팬스인 경우? 46 | // 수리하지 않고 이전까지의 수리 비용을 사용하자 47 | answer = f(lastIndex - 1); 48 | } else { 49 | // 현재 팬스가 교체 범위의 오른쪽 끝이라고 하자 50 | // 즉, [previousIndex, lastIndex]범위를 모두 한 번에 교체할 때 최소 비용 51 | for (int previousIndex = 0; previousIndex <= lastIndex; previousIndex += 1) { 52 | double newCost = 0; 53 | newCost += sqrt(lastIndex - previousIndex + 1); 54 | newCost += f(previousIndex - 1); 55 | 56 | if (newCost < answer) { 57 | answer = newCost; 58 | } 59 | } 60 | } 61 | 62 | memo[lastIndex] = answer; 63 | return memo[lastIndex]; 64 | } 65 | 66 | }; 67 | 68 | int main() { 69 | string str; 70 | cin >> str; 71 | 72 | FenceRepairing problem(str); 73 | double answer = problem.f(str.length() - 1); 74 | 75 | cout << fixed << setprecision(3) << answer << endl; 76 | } 77 | -------------------------------------------------------------------------------- /chapter09/problem_d/Main.java: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | import java.util.*; 3 | import java.lang.*; 4 | 5 | 6 | public class Main { 7 | public static final Scanner scanner = new Scanner(System.in); 8 | 9 | public static void main(String[] args) { 10 | int n = scanner.nextInt(); 11 | int[][] costMap = new int[n][n]; 12 | for (int r = 0; r < n; r += 1) { 13 | for (int c = 0; c < n; c += 1) { 14 | costMap[r][c] = scanner.nextInt(); 15 | } 16 | } 17 | 18 | Solution solution = new Solution(costMap); 19 | int answer = solution.f(n-1,n-1); 20 | 21 | System.out.println(answer); 22 | } 23 | } 24 | 25 | 26 | class Solution { 27 | private static final int EMPTY = -1; 28 | private static final int INFINITY = 1000000000; 29 | 30 | private int[][] cost; 31 | private int[][] memo; 32 | private int n; 33 | 34 | public Solution(int[][] costMap) { 35 | int n = costMap.length; 36 | this.cost = new int[n][n]; 37 | this.memo = new int[n][n]; 38 | for (int i = 0; i < n; i += 1) { 39 | for (int j = 0; j < n; j += 1) { 40 | this.cost[i][j] = costMap[i][j]; 41 | this.memo[i][j] = EMPTY; 42 | } 43 | } 44 | } 45 | 46 | 47 | /** 48 | * (0, 0) ~ (lastRow, lastCol)까지만 고려했을 때 문제의 정답 49 | * 50 | * @param lastRow 51 | * @param lastCol 52 | * @return 최단경로들 중 가장 작은 난이도 합 53 | */ 54 | public int f(int lastRow, int lastCol) { 55 | if (lastCol < 0 || lastRow < 0) { 56 | return INFINITY; 57 | } else if (memo[lastRow][lastCol] != EMPTY) { 58 | return memo[lastRow][lastCol]; 59 | } else if (lastRow == 0 && lastCol == 0) { 60 | return cost[0][0]; 61 | } 62 | 63 | int answer = Math.min( 64 | f(lastRow - 1, lastCol) + cost[lastRow][lastCol], 65 | f(lastRow, lastCol - 1) + cost[lastRow][lastCol] 66 | ); 67 | 68 | memo[lastRow][lastCol] = answer; 69 | return answer; 70 | } 71 | 72 | } -------------------------------------------------------------------------------- /chapter09/problem_d/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int INF = 987654321; 8 | 9 | class Solution { 10 | public: 11 | vector > cost; 12 | vector > memo; 13 | int n; 14 | 15 | Solution(vector > costMap) { 16 | this->n = costMap.size(); 17 | this->cost = costMap; 18 | this->memo = vector >(this->n, vector(this->n, -1)); 19 | } 20 | 21 | 22 | /** 23 | * (0, 0) ~ (lastRow, lastCol)까지만 고려했을 때 문제의 정답 24 | * 25 | * @param lastRow 26 | * @param lastCol 27 | * @return 최단경로들 중 가장 작은 난이도 합 28 | */ 29 | int f(int lastRow, int lastCol) { 30 | if (lastCol < 0 || lastRow < 0) { 31 | return INF; 32 | } else if (memo[lastRow][lastCol] != -1) { 33 | return memo[lastRow][lastCol]; 34 | } else if (lastRow == 0 && lastCol == 0) { 35 | return cost[0][0]; 36 | } 37 | 38 | int answer = min( 39 | f(lastRow - 1, lastCol) + cost[lastRow][lastCol], 40 | f(lastRow, lastCol - 1) + cost[lastRow][lastCol] 41 | ); 42 | 43 | memo[lastRow][lastCol] = answer; 44 | return answer; 45 | } 46 | 47 | }; 48 | 49 | int main() { 50 | int n; 51 | scanf("%d", &n); 52 | 53 | vector > costMap(n, vector(n)); 54 | for (int i = 0; i < n ; i += 1) { 55 | for (int j = 0; j < n; j += 1) { 56 | scanf("%d", &costMap[i][j]); 57 | } 58 | } 59 | 60 | 61 | Solution solution(costMap); 62 | int answer = solution.f(n - 1, n - 1); 63 | 64 | printf("%d\n", answer); 65 | } 66 | -------------------------------------------------------------------------------- /chapter09/problem_e/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | 8 | class RangeSum { 9 | public: 10 | vector > memo; 11 | vector > values; 12 | int n; 13 | 14 | RangeSum(vector > values) { 15 | this->n = values.size(); 16 | this->values = values; 17 | this->memo = vector >(this->n, vector(this->n, -1)); 18 | } 19 | 20 | /** 21 | * values[0][0] ~ values[lastRow][lastCol] 까지의 직사각형 누적합을 계산하는 함수 22 | * 23 | * @param lastRow 마지막 행 번호 24 | * @param lastCol 마지막 열 번호 25 | * @return 해당 범위의 누적합 26 | */ 27 | int f(int lastRow, int lastCol) { 28 | if (lastCol < 0 || lastRow < 0) { 29 | return 0; 30 | } else if (memo[lastRow][lastCol] != -1) { 31 | return memo[lastRow][lastCol]; 32 | } else if (lastRow == 0 && lastCol == 0) { 33 | return values[0][0]; 34 | } 35 | 36 | memo[lastRow][lastCol] = values[lastRow][lastCol] + f(lastRow - 1, lastCol) + f(lastRow, lastCol - 1) - f(lastRow - 1, lastCol - 1); 37 | 38 | return memo[lastRow][lastCol]; 39 | } 40 | }; 41 | 42 | int main() { 43 | int n, m; 44 | scanf("%d%d", &n, &m); 45 | 46 | vector > values(n, vector(n)); 47 | for (int i = 0; i < n; i += 1) { 48 | for (int j = 0; j < n; j += 1) { 49 | scanf("%d", &values[i][j]); 50 | } 51 | } 52 | 53 | RangeSum rangeSum(values); 54 | 55 | for (int i = 0; i < m; i += 1) { 56 | int minRow, minCol, maxRow, maxCol; 57 | scanf("%d%d%d%d", &minRow, &minCol, &maxRow, &maxCol); 58 | minRow -= 1; minCol -= 1; maxRow -= 1; maxCol -= 1; 59 | 60 | int sum = 0; 61 | sum += rangeSum.f(maxRow, maxCol); 62 | sum -= rangeSum.f(maxRow, minCol - 1); 63 | sum -= rangeSum.f(minRow - 1, maxCol); 64 | sum += rangeSum.f(minRow - 1, maxCol - 1); 65 | 66 | printf("%d\n", sum); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /chapter09/problem_f/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int INF = 987654321; 8 | 9 | class Quilting { 10 | public: 11 | vector > imgA, imgB, memo; 12 | int r, c; 13 | 14 | Quilting(int r, int c, vector > imgA, vector > imgB) { 15 | this->r = r; 16 | this->c = c; 17 | this->imgA = imgA; 18 | this->imgB = imgB; 19 | this->memo = vector >(r, vector(c, -1)); 20 | } 21 | 22 | /** 23 | * 현재 0번째 행부터 이어온 경계선의 마지막이 (lastRow, lastCol)일 때 최소의 부자연스러움 수치를 계산하는 함수 24 | * 25 | * @param lastRow 경계선 마지막 행 26 | * @param lastCol 경계선 마지막 열 27 | * @return 이때의 최소 부자연스러움 28 | */ 29 | int f(int lastRow, int lastCol) { 30 | if (lastRow < 0 || lastCol < 0 || lastCol >= c) { 31 | return INF; 32 | } else if (memo[lastRow][lastCol] != -1) { 33 | return memo[lastRow][lastCol]; 34 | } else if (lastRow == 0) { 35 | int diff = imgA[lastRow][lastCol] - imgB[lastRow][lastCol]; 36 | return diff * diff; 37 | } 38 | 39 | // 일단 현재 픽셀의 차이값을 계산한다 40 | int diff = imgA[lastRow][lastCol] - imgB[lastRow][lastCol]; 41 | int error = diff * diff; 42 | 43 | // 이전 행 까지의 세가지 경우의 수중 최적해와 더한다 44 | int answer = error + min(f(lastRow - 1, lastCol - 1), min(f(lastRow - 1, lastCol), f(lastRow - 1, lastCol + 1))); 45 | memo[lastRow][lastCol] = answer; 46 | return answer; 47 | } 48 | }; 49 | 50 | int main() { 51 | int r, c; 52 | scanf("%d%d", &r, &c); 53 | vector > imgA(r, vector(c)); 54 | vector > imgB(r, vector(c)); 55 | 56 | for (int i = 0; i < r; i += 1) { 57 | for (int j = 0; j < c; j += 1) { 58 | scanf("%d", &imgA[i][j]); 59 | } 60 | } 61 | 62 | for (int i = 0; i < r; i += 1) { 63 | for (int j = 0; j < c; j += 1) { 64 | scanf("%d", &imgB[i][j]); 65 | } 66 | } 67 | 68 | Quilting quilting(r, c, imgA, imgB); 69 | 70 | int answer = quilting.f(r - 1, c - 1); 71 | 72 | printf("%d\n", answer); 73 | } 74 | -------------------------------------------------------------------------------- /chapter09/problem_g/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | class LCS { 9 | public: 10 | vector > memo; 11 | string strA, strB; 12 | 13 | LCS(string strA, string strB) { 14 | this->strA = strA; 15 | this->strB = strB; 16 | this->memo = vector >(strA.length(), vector(strB.length(), -1)); 17 | } 18 | 19 | /** 20 | * 부분 문자열 A[0..lastIndexA]와 B[0..lastIndexB] 사이의 LCS길이 21 | * 22 | * @param lastIndexA 문자열 A의 마지막 문자 인덱스 23 | * @param lastIndexB 문자열 B의 마지막 문자 인덱스 24 | * @return 해당 부분 문자 열사이의 LCS길이 25 | */ 26 | int f(int lastIndexA, int lastIndexB) { 27 | if (lastIndexA < 0 || lastIndexB < 0) { 28 | // 둘 중 하나가 빈 문자열인 경우는 0 29 | return 0; 30 | } else if (memo[lastIndexA][lastIndexB] != -1) { 31 | // 이미 계산된 값인 경우 32 | return memo[lastIndexA][lastIndexB]; 33 | } 34 | 35 | int caseA = f(lastIndexA - 1, lastIndexB); // A[i]를 제외하고 계산한 LCS 36 | int caseB = f(lastIndexA, lastIndexB - 1); // B[j]를 제외하고 계산한 LCS 37 | int caseC = f(lastIndexA - 1, lastIndexB - 1); // A[i], B[j]를 모두 제외하고 계산한 LCS 38 | if (strA[lastIndexA] == strB[lastIndexB]) { 39 | caseC += 1; // 만약 A[i], B[j]가 일치한다면 LCS길이 + 1 40 | } 41 | 42 | int answer = max(caseA, max(caseB, caseC)); 43 | 44 | memo[lastIndexA][lastIndexB] = answer; 45 | return answer; 46 | } 47 | }; 48 | 49 | int main() { 50 | string strA, strB; 51 | cin >> strA >> strB; 52 | 53 | LCS lcs(strA, strB); 54 | int answer = lcs.f(strA.length() - 1, strB.length() - 1); 55 | 56 | printf("%d\n", answer); 57 | } 58 | -------------------------------------------------------------------------------- /chapter09/problem_h/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int INF = 987654321; 8 | 9 | class DTW { 10 | public: 11 | vector signA, signB; 12 | vector > memo; 13 | 14 | DTW(vector signA, vector signB) { 15 | this->signA = signA; 16 | this->signB = signB; 17 | this->memo = vector >(signA.size(), vector(signB.size(), -1)); 18 | } 19 | 20 | /** 21 | * 두 부분 파형 signA[0..lastIndexA], signB[0..lastIndexB]에 대한 최소의 거리 22 | * signA[lastIndexA]와 signB[lastIndexB]는 반드시 대응되어야 한다. 23 | * 24 | * @param lastIndexA 25 | * @param lastIndexB 26 | * @return 두 부분 파형에대한 최소 거리 27 | */ 28 | int f(int lastIndexA, int lastIndexB) { 29 | if (lastIndexA < 0 || lastIndexB < 0) { 30 | return INF; 31 | } else if (memo[lastIndexA][lastIndexB] != -1) { 32 | return memo[lastIndexA][lastIndexB]; 33 | } else if (lastIndexA == 0 && lastIndexB == 0) { 34 | int diff = signA[0] - signB[0]; 35 | return diff * diff; 36 | } 37 | 38 | int diff = signA[lastIndexA] - signB[lastIndexB]; 39 | int error = diff * diff; 40 | 41 | int answer = error + min(f(lastIndexA - 1, lastIndexB), min(f(lastIndexA, lastIndexB - 1), f(lastIndexA - 1, lastIndexB - 1))); 42 | memo[lastIndexA][lastIndexB] = answer; 43 | 44 | return answer; 45 | } 46 | }; 47 | 48 | int main() { 49 | int n; 50 | scanf("%d", &n); 51 | vector signA(n), signB(n); 52 | 53 | for (int i = 0; i < n; i += 1) { 54 | scanf("%d", &signA[i]); 55 | } 56 | 57 | for (int i = 0; i < n; i += 1) { 58 | scanf("%d", &signB[i]); 59 | } 60 | 61 | DTW dtw(signA, signB); 62 | 63 | int answer = dtw.f(n - 1, n - 1); 64 | printf("%d\n", answer); 65 | } 66 | -------------------------------------------------------------------------------- /chapter11/problem_c/Main.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.lang.*; 3 | import java.io.*; 4 | 5 | public class Main { 6 | public static final Scanner scanner = new Scanner(System.in); 7 | public static final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out)); 8 | 9 | public static void main(String[] args) throws Exception { 10 | String P = scanner.next(); 11 | int M = P.length(); 12 | 13 | int[] PI = getFailureFunctionTable(P); 14 | 15 | for (int i = 0; i < M; i += 1) { 16 | writer.write(String.format("%d\n", PI[i])); 17 | } 18 | 19 | writer.close(); 20 | } 21 | 22 | /** 23 | * 문자열 P에 대한 부분 매칭 테이블을 계산하여 반환해주는 함수 24 | * 25 | * @param P 테이블을 계산할 패턴 문자열 26 | * @return 부분 매칭 테이블 27 | */ 28 | public static int[] getFailureFunctionTable(String P) { 29 | String S = P; 30 | int N = S.length(); // 탐색 대상 문자열 (자기자신) 31 | int M = P.length(); // 패턴 문자열 32 | int[] PI = new int[M]; 33 | 34 | int begin = 1; // 자기 자신을 찾는 경우를 무시하기 위해 1부터 시작 35 | int matched = 0; 36 | 37 | while (begin + matched < N) { 38 | if (S.charAt(begin + matched) == P.charAt(matched)) { 39 | matched += 1; 40 | // P[0..(matched-1)] == P[begin..(begin+matched-1)] 이다. 41 | // 즉, 부분 문자열 P[0..(begin-matched-1)]은 좌우 matched글자 만큼 공통 접두/접미사가 있다. 42 | PI[begin + matched - 1] = matched; 43 | } else { 44 | // KMP와 똑같이 수행한다. 45 | if (matched == 0) { 46 | begin += 1; 47 | } else { 48 | begin += matched - PI[matched - 1]; 49 | matched = PI[matched - 1]; 50 | } 51 | } 52 | } 53 | return PI; 54 | } 55 | } 56 | --------------------------------------------------------------------------------