diff --git "a/03_\354\240\225\354\210\230\353\241\240/\355\225\204\354\210\230/1735.cpp" "b/03_\354\240\225\354\210\230\353\241\240/\355\225\204\354\210\230/1735.cpp" deleted file mode 100644 index 6ef3c47..0000000 --- "a/03_\354\240\225\354\210\230\353\241\240/\355\225\204\354\210\230/1735.cpp" +++ /dev/null @@ -1,38 +0,0 @@ -#include - -using namespace std; - -// 최대공약수(GCD) 계산 함수: 유클리드 호제법 이용 -int getGCD(int a, int b) { - // 만약 b가 0이면, a가 최대공약수이다. - if (b == 0) return a; - // 그렇지 않으면, b와 a를 b로 나눈 나머지로 재귀 호출한다. - return getGCD(b, a % b); -} - -/* - [백준 1735: 분수 합] - a/b + c/d = (a*d)/(b*d) + (b*c)/(b*d) = (a*d + b*c)/(b*d) - 위 분수를 기약분수로 나타낸 것을 x/y라 하고, - gcd를 (a*d + b*c)와 (b*d)의 최대공약수라 하면 - x = (a*d + b*c) / gcd - y = (b*d) / gcd -*/ - -int main() { - // 입력 - int a, b, c, d; - cin >> a >> b >> c >> d; - - // 연산 - int x = (a * d) + (b * c); // 분자 - int y = b * d; // 분모 - int gcd = getGCD(x, y); - x = x / gcd; // 기약분수의 분자 - y = y / gcd; // 기약분수의 분모 - - // 출력 - cout << x << " " << y; - - return 0; -} diff --git "a/03_\354\240\225\354\210\230\353\241\240/\355\225\204\354\210\230/2840.cpp" "b/03_\354\240\225\354\210\230\353\241\240/\355\225\204\354\210\230/2840.cpp" deleted file mode 100644 index a3e6b3f..0000000 --- "a/03_\354\240\225\354\210\230\353\241\240/\355\225\204\354\210\230/2840.cpp" +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include - -using namespace std; - -typedef pair ic; // pair의 간단한 별칭 정의 -const int ALPHA = 26; // 알파벳의 개수 상수로 정의 - -// index부터 시계방향으로 바퀴에 적어놓은 알파벳 출력 -string printWheel(int n, int index, vector& wheel) { - string ans = ""; - // 바퀴를 돌릴 때와 반대방향으로 출력 - for (int i = index + n; i > index; i--) { - ans += wheel[i % n]; - } - return ans; -} - -// 행운의 바퀴 반환 -string makeWheel(int n, int k, vector& record) { - vector wheel(n, '?'); // 바퀴의 모든 알파벳을 ?로 초기화 - vector is_available(ALPHA, false); // 알파벳 중복 체크 - - int index = 0; // 화살표가 가리키는 인덱스 - - for (int i = 0; i < k; i++) { - int s = record[i].first; // 화살표가 가리키는 글자가 변하는 횟수 - char ch = record[i].second; // 회전을 멈추었을 때 가리키던 글자 - - index = (index + s) % n; // 회전한 후 화살표가 가리키는 인덱스 - - // 해당 칸이 ch로 이미 채워져 있는 경우 넘어감 - if (wheel[index] == ch) { - continue; - } - - // 다른 글자로 채워져있거나 해당 글자가 이미 사용된 알파벳인 경우 ! 반환 - if (wheel[index] != '?' || is_available[ch - 'A']) { - return "!"; - } - - wheel[index] = ch; // 해당 칸에 글자 적기 - is_available[ch - 'A'] = true; // 해당 알파벳이 사용되었으므로 true로 변경 - } - return printWheel(n, index, wheel); -} - -int main() { - ios::sync_with_stdio(false); // C++ 입출력 성능 향상을 위한 설정 - cin.tie(NULL); // cin과 cout의 tie 해제 - cout.tie(NULL); - - // 입력 - int n, k; - cin >> n >> k; - - //record에 값 입력 - vector record(k); - for (int i = 0; i < k; i++) { - cin >> record[i].first >> record[i].second; - } - - // 연산 & 출력 - cout << makeWheel(n, k, record); - - return 0; -} diff --git "a/03_\354\240\225\354\210\230\353\241\240/\355\225\204\354\210\230/6588.cpp" "b/03_\354\240\225\354\210\230\353\241\240/\355\225\204\354\210\230/6588.cpp" deleted file mode 100644 index 7e6a1f4..0000000 --- "a/03_\354\240\225\354\210\230\353\241\240/\355\225\204\354\210\230/6588.cpp" +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include - -using namespace std; - -// 소수 여부 반환 함수: 에라토스테네스의 체 이용 -vector getPrimes(int n) { - vector is_prime(n + 1, true); - is_prime[0] = is_prime[1] = false; - - // 에라토스테네스의 체 알고리즘을 사용하여 소수 여부 판별 - for (int i = 2; i * i <= n; i++) { - if (!is_prime[i]) { - continue; - } - for (int j = i * i; j <= n; j += i) { - is_prime[j] = false; - } - } - return is_prime; -} - -// n = a + b를 만족시키는 a 반환 -int goldbach(int n, vector &is_prime) { - for (int a = 3; a <= n / 2; a += 2) { - // 2보다 큰 짝수 소수는 존재하지 않으므로 - // a = 3부터 탐색해도 a와 b 모두 홀수여야 한다는 조건 만족 - if (is_prime[a] && is_prime[n - a]) { - return a; - } - } - // n = a + b를 만족시키는 홀수 소수 a, b가 없으면 0 반환 - return 0; -} - -/* - [백준 6588: 골드바흐의 추측] - 1. 3보다 크거나 같고 n / 2보다 작거나 같은 소수 a를 오름차순으로 탐색한다. - 2. 1에서 찾은 a에 대하여 n - a(=b)도 소수이면 골드바흐의 추측이 성립한다. - 3. 골드바흐의 추측이 성립하면 a를, 성립하지 않으면 0을 반환한다. -*/ - -int main() { - // 입력 - vector arr; - int input; - - // 0이 입력될 때까지 숫자를 입력받아 벡터에 저장 - while (1) { - cin >> input; - if (input == 0) { - break; - } - arr.push_back(input); - } - - // 연산 - int max_num = *max_element(arr.begin(), arr.end()); - vector is_prime = getPrimes(max_num); - - for (int i = 0; i < arr.size(); i++) { - int a = goldbach(arr[i], is_prime); - - // 출력 - if (a != 0) { // n = a + b를 만족하는 a, b가 존재하면 - cout << arr[i] << " = " << a << " + " << arr[i] - a << "\n"; - } else { // 존재하지 않으면 - cout << "Goldbach's conjecture is wrong.\n"; - } - } - return 0; -} \ No newline at end of file diff --git "a/06_greedy_algorithm/\355\225\204\354\210\230/1213_h.cpp" "b/06_greedy_algorithm/\355\225\204\354\210\230/1213_h.cpp" deleted file mode 100644 index 2101576..0000000 --- "a/06_greedy_algorithm/\355\225\204\354\210\230/1213_h.cpp" +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include - -using namespace std; - -// 주어진 문자열이 팰린드롬이 될 수 있는지 문자열의 알파벳과 그 개수를 저장한 맵을 통해 체크하는 함수 -bool checkPalindrome(char& odd_alp, const map& alp_cnt) { - int odd_cnt = 0; - for (auto iter : alp_cnt) { - if (iter.second % 2 == 1) { // 개수가 홀수인 알파벳이 있을 때 - odd_alp = iter.first; // 그 알파벳을 저장 - odd_cnt++; // 홀수 카운트 증가 - if (odd_cnt == 2) { // 홀수인 알파벳이 1개 초과 -> 팰린드롬 불가. - return false; - } - } - } - return true; -} - -// 주어진 문자열을 팰린드롬으로 만드는 함수 -string makePalindrome(int name_len, char odd_alp, map alp_cnt) { - string answer = ""; - - for (auto iter : alp_cnt) { - // 사전 순으로 정렬된 알파벳을 등장 횟수의 절반만 빈 문자열에 추가. - for (int i = 0; i < iter.second / 2; i++) { - answer += iter.first; - } - } - - if (odd_alp != 'a') { // 홀수 갯수의 알파벳이 존재할 때 - answer += odd_alp; // 가운데에 추가 - } - for (int i = name_len / 2 - 1; i >= 0; i--) { - answer += answer[i]; // 문자열을 뒤집어서 뒤에 추가. - } - return answer; -} - -int main() { - int name_len; // 주어진 문자열의 길이 - char odd_alp = 'a'; // 등장 횟수가 홀수인 알파벳 - string name; // 주어진 문자열 - map alp_cnt; // 문자열 내 알파벳과 각각의 개수를 저장하는 맵 - - // 입력 - cin >> name; - name_len = name.length(); - - for (int i = 0; i < name_len; i++) { - alp_cnt[name[i]]++; // 알파벳의 개수를 저장하는 맵을 생성. - } - - // 팰린드롬이 될 수 있는지 확인 - if (!checkPalindrome(odd_alp, alp_cnt)) { - cout << "I'm Sorry Hansoo"; - return 0; - } - - // 가능할 경우 팰린드롬 출력 - cout << makePalindrome(name_len, odd_alp, alp_cnt); -} diff --git "a/06_greedy_algorithm/\355\225\204\354\210\230/17451_h.cpp" "b/06_greedy_algorithm/\355\225\204\354\210\230/17451_h.cpp" deleted file mode 100644 index 2101576..0000000 --- "a/06_greedy_algorithm/\355\225\204\354\210\230/17451_h.cpp" +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include - -using namespace std; - -// 주어진 문자열이 팰린드롬이 될 수 있는지 문자열의 알파벳과 그 개수를 저장한 맵을 통해 체크하는 함수 -bool checkPalindrome(char& odd_alp, const map& alp_cnt) { - int odd_cnt = 0; - for (auto iter : alp_cnt) { - if (iter.second % 2 == 1) { // 개수가 홀수인 알파벳이 있을 때 - odd_alp = iter.first; // 그 알파벳을 저장 - odd_cnt++; // 홀수 카운트 증가 - if (odd_cnt == 2) { // 홀수인 알파벳이 1개 초과 -> 팰린드롬 불가. - return false; - } - } - } - return true; -} - -// 주어진 문자열을 팰린드롬으로 만드는 함수 -string makePalindrome(int name_len, char odd_alp, map alp_cnt) { - string answer = ""; - - for (auto iter : alp_cnt) { - // 사전 순으로 정렬된 알파벳을 등장 횟수의 절반만 빈 문자열에 추가. - for (int i = 0; i < iter.second / 2; i++) { - answer += iter.first; - } - } - - if (odd_alp != 'a') { // 홀수 갯수의 알파벳이 존재할 때 - answer += odd_alp; // 가운데에 추가 - } - for (int i = name_len / 2 - 1; i >= 0; i--) { - answer += answer[i]; // 문자열을 뒤집어서 뒤에 추가. - } - return answer; -} - -int main() { - int name_len; // 주어진 문자열의 길이 - char odd_alp = 'a'; // 등장 횟수가 홀수인 알파벳 - string name; // 주어진 문자열 - map alp_cnt; // 문자열 내 알파벳과 각각의 개수를 저장하는 맵 - - // 입력 - cin >> name; - name_len = name.length(); - - for (int i = 0; i < name_len; i++) { - alp_cnt[name[i]]++; // 알파벳의 개수를 저장하는 맵을 생성. - } - - // 팰린드롬이 될 수 있는지 확인 - if (!checkPalindrome(odd_alp, alp_cnt)) { - cout << "I'm Sorry Hansoo"; - return 0; - } - - // 가능할 경우 팰린드롬 출력 - cout << makePalindrome(name_len, odd_alp, alp_cnt); -} diff --git "a/06_greedy_algorithm/\355\225\204\354\210\230/18111_h.cpp" "b/06_greedy_algorithm/\355\225\204\354\210\230/18111_h.cpp" deleted file mode 100644 index c3bf475..0000000 --- "a/06_greedy_algorithm/\355\225\204\354\210\230/18111_h.cpp" +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include - -using namespace std; - -typedef pair pii; - -const int MAX_HEIGHT = 257; // 블록 높이의 최댓값 -const int INF = 987'654'321; // 무한대를 나타내는 값, 최댓값이 12,800,000이므로 큰 수인 987654321을 사용 - -// 모든 땅의 높이를 height로 만드는 비용 계산 함수 -int calcCost(int height, int n, int m, int b, vector>& blocks) { - int cost = 0; - int added = 0; // 추가해야 하는 블록의 총 개수 - int removed = 0; // 제거해야 하는 블록의 총 개수 - - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) { - int gap = abs(height - blocks[i][j]); - - if (blocks[i][j] > height) { - // 목표 높이보다 높은 칸인 경우, gap개의 블록 제거 - removed += gap; - } else if (blocks[i][j] < height) { - // 목표 높이보다 낮은 칸인 경우, gap개의 블록 추가 - added += gap; - } - } - } - - // 전체 비용 계산 - cost = 2 * removed + added; - - // 블록 개수가 부족하다면 모든 땅의 높이를 height로 만드는 것이 불가능 - return (added > (b + removed)) ? INF : cost; -} - -// 모든 땅의 높이를 같게 만드는 최소 비용과 그 때의 땅의 높이를 반환하는 함수 -pii makeGroundEven(int n, int m, int b, vector>& ground) { - int minCost = INF; - int height = 0; - - // 모든 높이를 다 만들어보고 최소 비용 찾기 - for (int i = 0; i < MAX_HEIGHT; i++) { - int cost = calcCost(i, n, m, b, ground); - if (cost <= minCost) { - minCost = cost; - height = i; - } - } - - return {minCost, height}; -} - -/** - * 블록 높이의 최댓값이 256밖에 되지 않으므로 - * 모든 칸을 높이 n(0~256)으로 만드는 모든 경우를 시도해보고 - * 그 중에서 비용이 최소가 될 때를 찾는다. - */ - -int main() { - int n, m, b; - - // 입력 - cin >> n >> m >> b; - vector> ground(n, vector(m)); - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) { - cin >> ground[i][j]; - } - } - - // 연산 - pii answer = makeGroundEven(n, m, b, ground); - - // 출력 - cout << answer.first << " " << answer.second << "\n"; - - return 0; -} diff --git "a/09_backtracking/\355\225\204\354\210\230/14888.cpp" "b/09_backtracking/\355\225\204\354\210\230/14888.cpp" deleted file mode 100644 index 7a2e512..0000000 --- "a/09_backtracking/\355\225\204\354\210\230/14888.cpp" +++ /dev/null @@ -1,68 +0,0 @@ -#include - -using namespace std; - -const int MAX_N = 11; - -int n; - -int min_num = 1000000001; -int max_num = -1000000001; - -int sequence[MAX_N]; // 수열 -int operators[4]; // 연산자 - -void updateAnswer(int ans) { - max_num = max(max_num, ans); - min_num = min(min_num, ans); -} - -void findMinMax(int ans, int cnt) -{ - //재귀 호출 종료 조건 : 수열의 값을 다 사용하였을 경우 - if(cnt == n) - { - updateAnswer(ans); - return; - } - - //i : 연산자 종류 - for(int i = 0; i < 4; i++) - { - // 연산자를 다 쓰지 않은 경우만 - if(operators[i] > 0) - { - //연산자 사용 - operators[i]--; - - //rst 값 업데이트 및 다음 연산자 고르기 - if(i == 0) - findMinMax(ans + sequence[cnt], cnt + 1); - else if(i == 1) - findMinMax(ans - sequence[cnt], cnt + 1); - else if(i == 2) - findMinMax(ans * sequence[cnt], cnt + 1); - else - findMinMax(ans / sequence[cnt], cnt + 1); - - operators[i]++; // 연산자 반납 - } - } - return; -} - -int main() { - - //입력 - cin >> n; - for(int i = 0; i < n; i++) - cin >> sequence[i]; - for(int i = 0; i < 4; i++) - cin >> operators[i]; - - //연산 - findMinMax(sequence[0], 1); - - //출력 - cout << max_num << '\n' << min_num; -} \ No newline at end of file diff --git "a/09_backtracking/\355\225\204\354\210\230/15665.cpp" "b/09_backtracking/\355\225\204\354\210\230/15665.cpp" deleted file mode 100644 index c3ad893..0000000 --- "a/09_backtracking/\355\225\204\354\210\230/15665.cpp" +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include - -using namespace std; - -const int MAX_N = 8; - -int n, m; -int sequence[MAX_N]; -vector ans; - -void printSequence() { - for (int i = 0; i < m; i++) { - cout << ans[i] << " "; - } - cout << "\n"; -} - -void backtrack(int cnt, int start) -{ - // 재귀 호출 종료 조건 : M개의 숫자를 다 뽑은 경우 - if (cnt == m) - { - printSequence(); - return; - } - - //i : 고르려는 수 - int prev_num = -1; // 이전에 선택한 숫자를 기억하기 위한 변수 - for (int i = 0; i < n; i++) - { - // 중복 선택 허용, 중복된 숫자를 생성하지 않도록 조건 추가 - if (sequence[i] != prev_num) { - //사용 - ans.push_back(sequence[i]); - prev_num = sequence[i]; - - //다음 숫자 고르기 - backtrack(cnt + 1, i + 1); - - //반납 - ans.pop_back(); - } - } -} - -int main() -{ - //입력력 - cin >> n >> m; - for (int i = 0; i < n; i++) - cin >> sequence[i]; - - //연산 및 출력 - sort(sequence, sequence + n); // 입력된 숫자 배열을 정렬 - - backtrack(0, 0); // 조합 생성 시작 -} diff --git "a/09_backtracking/\355\225\204\354\210\230/20055.cpp" "b/09_backtracking/\355\225\204\354\210\230/20055.cpp" deleted file mode 100644 index 3448263..0000000 --- "a/09_backtracking/\355\225\204\354\210\230/20055.cpp" +++ /dev/null @@ -1,91 +0,0 @@ -#include -#include - -using namespace std; - -struct info { // 내구도와 로봇 존재 여부를 나타내는 구조체 - int power; // 컨베이어 벨트의 칸 내구도 - bool is_on; // 해당 칸에 로봇이 존재하는지 여부 -}; - -// 컨베이어 벨트 한 칸 회전 함수 -void rotateBelt(deque &belt, int n) { - belt.push_front(belt.back()); // 맨 뒤의 칸을 앞으로 이동 - belt.pop_back(); // 맨 뒤의 칸 제거 - belt[n - 1].is_on = false; // 로봇이 내리는 위치에서 로봇 제거 -} - -// 로봇을 이동시킬 수 있는 경우 이동하는 함수 -void moveRobot(deque &belt, int n) { - for (int i = n - 2; i >= 0; i--) { - if (!belt[i].is_on) { - continue; // 해당 칸에 로봇이 없으면 다음 칸으로 이동 - } - - if (!belt[i + 1].is_on && (belt[i + 1].power >= 1)) { - // 다음 칸이 비어있고 내구도가 남아있을 때 로봇 이동 - belt[i].is_on = false; - belt[i + 1].is_on = true; - belt[i + 1].power--; - } - - belt[n - 1].is_on = false; // 로봇이 내리는 위치에서 로봇 제거 - } -} - -// 로봇을 컨베이어 벨트에 올릴 수 있는 경우 로봇을 올리는 함수 -void putRobot(deque &belt) { - if (!belt[0].is_on && belt[0].power >= 1) { - // 로봇이 없고 내구도가 남아있는 경우 로봇을 올림 - belt[0].is_on = true; - belt[0].power--; - } -} - -// 컨베이어 벨트의 내구도를 확인하여 작업 종료 여부를 반환 -bool checkFinish(deque &belt, int n, int k) { - int count = 0; - - for (int i = 0; i < 2 * n; i++) { - if (belt[i].power == 0) { - count++; - } - } - - return count >= k; -} - -int solution(deque &belt, int n, int k) { - int step = 1; - while (true) { - // 컨베이어 벨트 회전 - rotateBelt(belt, n); - // 로봇 이동 - moveRobot(belt, n); - // 로봇 올리기 - putRobot(belt); - - // 내구도 체크 - if (checkFinish(belt, n, k)) { - return step; - } - step++; - } -} - -int main() { - // 입력 - int n, k; - cin >> n >> k; - deque belt(2 * n); // 컨베이어 벨트의 내구도와 로봇 존재 여부 저장 - for (int i = 0; i < 2 * n; i++) { - cin >> belt[i].power; - belt[i].is_on = false; - } - - // 연산 - int answer = solution(belt, n, k); - - // 출력 - cout << answer; -} \ No newline at end of file diff --git "a/10_binary_search/\353\217\204\354\240\204/2343.cpp" "b/10_binary_search/\353\217\204\354\240\204/2343.cpp" deleted file mode 100644 index f00a4c9..0000000 --- "a/10_binary_search/\353\217\204\354\240\204/2343.cpp" +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include -#include - -using namespace std; - -bool isPossible(vector& lessons, int m, int mid) { - int count = 1; - int sum = 0; - - for (int i = 0; i < lessons.size(); i++) { - if (sum + lessons[i] > mid) { - count++; - sum = lessons[i]; - } else { - sum += lessons[i]; - } - } - - return count <= m; -} - -int binarySearch(vector& lessons, int m) { - int left = *max_element(lessons.begin(), lessons.end()); - int right = accumulate(lessons.begin(), lessons.end(), 0); - int result = 0; - - while (left <= right) { - int mid = (left + right) / 2; - if (isPossible(lessons, m, mid)) { - result = mid; - right = mid - 1; - } else { - left = mid + 1; - } - } - - return result; -} - -int main() { - ios_base::sync_with_stdio(false); - cin.tie(NULL); - cout.tie(NULL); - - // 입력 - int n, m; - cin >> n >> m; - - vector lessons(n); - - for (int i = 0; i < n; i++) { - cin >> lessons[i]; - } - - // 연산 & 출력 - cout << binarySearch(lessons, m); - - return 0; -} diff --git "a/10_binary_search/\353\217\204\354\240\204/3079.cpp" "b/10_binary_search/\353\217\204\354\240\204/3079.cpp" deleted file mode 100644 index 6e318ad..0000000 --- "a/10_binary_search/\353\217\204\354\240\204/3079.cpp" +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include - -using namespace std; - -typedef long long ll; - -ll binarySearch(const vector& times, int n, int m) { - ll start = 1, end = static_cast(*max_element(times.begin(), times.end())) * m; - ll answer = 0; - - while (start <= end) { - ll mid = (start + end) / 2; - ll cnt = 0; - - for (int i = 0; i < n; i++) { - cnt += mid / times[i]; - if (cnt >= m) { - break; - } - } - - if (cnt >= m) { - answer = mid; - end = mid - 1; - } else { - start = mid + 1; - } - } - - return answer; -} - -int main() { - ios_base::sync_with_stdio(false); - cin.tie(NULL); - cout.tie(NULL); - - int n, m; - cin >> n >> m; - vector times(n); - - for (int i = 0; i < n; i++) { - cin >> times[i]; - } - - sort(times.begin(), times.end()); - - cout << binarySearch(times, n, m); - - return 0; -} diff --git "a/10_binary_search/\355\225\204\354\210\230/10815.cpp" "b/10_binary_search/\355\225\204\354\210\230/10815.cpp" deleted file mode 100644 index 8407cdb..0000000 --- "a/10_binary_search/\355\225\204\354\210\230/10815.cpp" +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include -#include - -using namespace std; - -int binarySearch(int n, int key, vector &nums) { - int left = 0; - int right = n - 1; - int mid; - - while(left <= right) { - mid = (left + right) / 2; - if (nums[mid] == key) { - return 1; - } - else if (nums[mid] > key) { - right = mid - 1; - } - else { - left = mid + 1; - } - } - return 0; -} - - -int main() { - ios_base::sync_with_stdio(false); - cin.tie(NULL); - cout.tie(NULL); - - int n, m, input; - - //입력 - cin >> n; - vector arr(n, 0); - - for (int i = 0; i < n; i++) { - cin >> arr[i]; - } - - cin >> m; - - //이분 탐색을 하기 위해 정렬 - sort(arr.begin(), arr.end()); - - //연산 & 출력 - while(m--) { - cin >> input; - cout << binarySearch(n, input, arr) << ' '; - } - - return 0; -} \ No newline at end of file diff --git "a/10_binary_search/\355\225\204\354\210\230/14500.cpp" "b/10_binary_search/\355\225\204\354\210\230/14500.cpp" deleted file mode 100644 index 974db0d..0000000 --- "a/10_binary_search/\355\225\204\354\210\230/14500.cpp" +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include - -using namespace std; - -vector> board; // 게임 보드를 나타내는 2D 벡터 -int ans; // 최대 결과를 저장할 변수 - -// 깊이 우선 탐색(Depth-First Search) 함수로 다양한 테트로미노 모양을 탐색 -void dfs(int x, int y, int depth, int sum) { - // 네 가지 방향으로 이동하기 위한 배열: 위, 오른쪽, 아래, 왼쪽 - vector dx = { -1, 0, 1, 0 }; - vector dy = { 0, 1, 0, -1 }; - - if (depth == 4) { // 네 개의 칸을 선택했을 경우, 최대 결과를 갱신 - ans = max(ans, sum); - return; - } - - for (int i = 0; i < 4; i++) { - // 다음에 선택할 칸의 좌표를 계산 - int nx = x + dx[i]; - int ny = y + dy[i]; - - if (nx < 0 || nx >= board.size() || ny < 0 || ny >= board[0].size() || !board[nx][ny]) { - // 셀이 범위를 벗어나거나 이미 방문한 경우 CONTINUE - continue; - } - - int temp = board[nx][ny]; // 방문하기 전 현재 셀의 값을 저장 - board[nx][ny] = 0; // 재방문을 피하기 위해 현재 셀을 방문 처리 - - if (depth == 2) { - // "ㅜ" 모양의 특수한 경우로, 현재 셀에서 다시 블록을 선택 - dfs(x, y, depth + 1, sum + temp); - } - - // 깊이와 합을 업데이트하여 다음 셀로 이동 - dfs(nx, ny, depth + 1, sum + temp); - - board[nx][ny] = temp; // 원래 값 복원 - } -} - -int main() { - //입력 - int n, m; - cin >> n >> m; - board.assign(n, vector(m, 0)); // 게임 보드의 크기를 n x m으로 초기화 - - // 게임 보드의 값 입력 - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) { - cin >> board[i][j]; - } - } - - // 각 셀에서 시작하여 테트로미노 모양을 찾기 위한 탐색을 수행 - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) { - int temp = board[i][j]; - board[i][j] = 0; // 시작 셀을 방문 처리 - dfs(i, j, 1, temp); // 깊이 1과 초기 합으로 DFS를 시작 - board[i][j] = temp; // 원래 값을 복원 - } - } - - // 출력 - cout << ans; - - return 0; -} diff --git "a/10_binary_search/\355\225\204\354\210\230/16401.cpp" "b/10_binary_search/\355\225\204\354\210\230/16401.cpp" deleted file mode 100644 index bb4d070..0000000 --- "a/10_binary_search/\355\225\204\354\210\230/16401.cpp" +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include - -using namespace std; - -bool isPossible(vector& lengths, int target, int m) { - int count = 0; - for (int i = 0; i < lengths.size(); i++) { - count += lengths[i] / target; - } - return count >= m; -} - -int binarySearch(vector& lengths, int m) { - int left = 1; - int right = lengths[lengths.size() - 1]; - int result = 0; - - while (left <= right) { - int mid = (left + right) / 2; - if (isPossible(lengths, mid, m)) { - result = mid; - left = mid + 1; - } else { - right = mid - 1; - } - } - - return result; -} - -int main () { - int m, n; - - //입력 - cin >> m >> n; - - vector arr(n, 0); - - for (int i = 0; i < n; i++) { - cin >> arr[i]; - } - - //연산 & 출력 - cout << binarySearch(arr, m); - - return 0; -} diff --git "a/13_shortest_path/\355\225\204\354\210\230/1238.cpp" "b/13_shortest_path/\355\225\204\354\210\230/1238.cpp" new file mode 100644 index 0000000..13f7364 --- /dev/null +++ "b/13_shortest_path/\355\225\204\354\210\230/1238.cpp" @@ -0,0 +1,70 @@ +#include // 입출력 라이브러리 +#include // 벡터 컨테이너 사용 +#include // 우선순위 큐 사용 + +using namespace std; // 표준 네임스페이스 사용 +typedef pair ci; // 정수 쌍에 대한 typedef +const int INF = 2e5; //최대 V-1개의 간선을 지나게 됨 -> V * (가중치 최대값) + +// 다익스트라 알고리즘: 시작 노드부터 다른 모든 노드까지의 최단 경로를 찾음 +vector dijkstra(int start, int v, vector>& graph) { + vector dist(v + 1, INF); // 각 정점까지의 최단 경로 저장 + priority_queue pq; // first: 시작점으로부터의 거리, second: 정점 + + // 시작 정점 초기화 + dist[start] = 0; + + pq.push({ 0, start }); // 거리가 0인 시작 노드를 우선순위 큐에 삽입 + + while (!pq.empty()) { + int w = -pq.top().first; // 현재 정점까지의 경로값 + int n = pq.top().second; // 현재 탐색하려는 정점 + pq.pop(); + if (w > dist[n]) { // 이미 더 작은 값으로 기록된 정점 + continue; + } + + for (auto [nxt_node, nxt_weight] : graph[n]) { // 다음 정점과 해당 정점까지의 가중치를 반복문으로 처리 + if (dist[nxt_node] > dist[n] + nxt_weight) { // 현재 정점을 거쳐서 가는 것이 더 짧은 경로인 경우 + dist[nxt_node] = dist[n] + nxt_weight; // 해당 정점까지의 최단 경로 갱신 + pq.push({ -dist[nxt_node], nxt_node }); // 최단 경로 우선순위 큐에 삽입 + } + } + } + return dist; +} + +int main() { + int v, e, k, a, b, w; + int answer = 0; + + // 입력 + cin >> v >> e >> k; + vector> graph(v + 1, vector(0)); // 인접 리스트 + + while (e--) { + cin >> a >> b >> w; + graph[a].push_back({ b, w }); // 방향 그래프 + } + + // 연산 + vector go(v + 1), back; + + // 정점 i에서 파티 장소까지 걸리는 시간 + for (int i = 1; i <= v; i++) { + vector tmp = dijkstra(i, v, graph); + go[i] = tmp[k]; + } + + // 파티 장소에서 다른 정점들까지 걸리는 시간 + back = dijkstra(k, v, graph); + + // 총 걸리는 시간 비교 + for (int i = 1; i <= v; i++) { + answer = max(answer, go[i] + back[i]); + } + + // 출력 + cout << answer; + return 0; +} diff --git "a/13_shortest_path/\355\225\204\354\210\230/15685.cpp" "b/13_shortest_path/\355\225\204\354\210\230/15685.cpp" new file mode 100644 index 0000000..789879b --- /dev/null +++ "b/13_shortest_path/\355\225\204\354\210\230/15685.cpp" @@ -0,0 +1,57 @@ +#include +#include + +using namespace std; + +const int MAX = 101; +bool board[MAX][MAX] = {false}; + +// 우 상 좌 하 +int dx[] = {1, 0, -1, 0}; +int dy[] = {0, -1, 0, 1}; + +void drawDragonCurve(int x, int y, int d, int g) { + vector directions = {d}; + for (int i = 0; i < g; ++i) { + int size = directions.size(); + for (int j = size - 1; j >= 0; --j) { + directions.push_back((directions[j] + 1) % 4); + } + } + + board[y][x] = true; + for (int dir : directions) { + x = x + dx[dir]; + y = y + dy[dir]; + board[y][x] = true; + } +} + +int countSquare() { + int cnt = 0; + for (int i = 0; i < MAX - 1; ++i) { + for (int j = 0; j < MAX - 1; ++j) { + if (board[i][j] && board[i][j + 1] && board[i + 1][j] && board[i + 1][j + 1]) + cnt++; + } + } + return cnt; +} + +int main() { + + //입력 + int N; + cin >> N; + + for (int i = 0; i < N; ++i) { + int x, y, d, g; + cin >> x >> y >> d >> g; + drawDragonCurve(x, y, d, g); + } + + //연산 & 출력 + cout << countSquare() << endl; + + return 0; +} diff --git "a/13_shortest_path/\355\225\204\354\210\230/2458.cpp" "b/13_shortest_path/\355\225\204\354\210\230/2458.cpp" new file mode 100644 index 0000000..58496c4 --- /dev/null +++ "b/13_shortest_path/\355\225\204\354\210\230/2458.cpp" @@ -0,0 +1,61 @@ +#include +#include + +using namespace std; + +const int INF = 6e8; + +void floydWarshall(int n, vector> &graph) { + for (int k = 1; k <= n; k++) { // 중간 정점 + for (int i = 1; i <= n; i++) { // 출발 정점 + for (int j = 1; j <= n; j++) { // 도착 정점 + // 중간에 k를 거쳐서 i에서 j로 갈 때의 비용 + int cost = graph[i][k] + graph[k][j]; + // 더 짧은 경로 선택 + graph[i][j] = min(graph[i][j], cost); + } + } + } +} + +int findAnswer(int n, vector> &graph) { + int answer = 0; + for (int i = 1; i <= n; ++i) { + int cnt = 0; + for (int j = 1; j <= n; ++j) { + if (i != j && (graph[i][j] != INF || graph[j][i] != INF)) { + cnt++; + } + } + if (cnt == n - 1) { + answer++; + } + } + return answer; +} + +int main() { + int N, M; + //입력 + cin >> N >> M; + + vector> graph(N + 1, vector(N + 1, INF)); + + for (int i = 1; i <= N; ++i) { + graph[i][i] = 0; // 자기 자신과의 거리 + } + + while(M--) { + int a, b; + cin >> a >> b; + graph[a][b] = 1; // a가 b보다 작음을 나타내는 정보 + } + + //연산 + floydWarshall(N, graph); + + //출력 + cout << findAnswer(N, graph) << '\n'; + + return 0; +}