알고리즘 102

[알고리즘] 그래프 순회 문제

그래프 탐색개요 그래프 탐색(graph traversal problem), 또는 그래프 순회 문제(graph search problem)는 그래프의 일련의 정점을 체계적으로 방문하는 문제를 의미한다. 주어진 그래프 G = 에서 특정 정점 s를 시작점으로 하여, 모든 정점 v ∈ V를 한 번씩 방문하는 것이 이 문제의 목표다. 이 과정에서 방문된 정점의 순서는 탐색 알고리즘에 따라 달라진다. 탐색은 주로 그래프의 구조를 이해하거나, 특정 경로를 찾는 등의 목적으로 사용된다. 이를 통해 네트워크 연결 상태, 최단 경로, 사이클 등 그래프의 다양한 특성을 분석할 수 있다.  그래프 탐색은 다양한 응용 분야에서 중요한 역할을 수행한다. 예를 들어, 네트워크 라우팅, SNS에서 친구 추천, 웹 크롤러 등에서 그래..

CS/알고리즘 2023.06.14

[백준] 1655 가운데를 말해요 with C++

문제설명 입출력 예제 개념 이 문제는 각 숫자를 입력받을 때마다 중간값을 계산하고 출력하는 것이다. 단순하게 배열에 값을 추가하고, 매 반복마다 중앙값을 출력하려면 시간 복잡도가 O(N^2)이 되어 시간 초과가 발생할 수 있다. 이를 해결하기 위한 최적화된 알고리즘이 두 힙 알고리즘이다. 두 힙 알고리즘은 최대 힙과 최소 힙을 이용한다. 이 방식에서는 현재까지 입력받은 수 중 중간값 이하의 수를 최대 힙에, 중간값 초과의 수를 최소 힙에 저장한다. 따라서 중간값은 항상 최대 힙의 루트에 위치하게 된다. 이 알고리즘의 각 연산은 로그 시간 복잡도를 가지므로, 전체 시간 복잡도는 입력의 개수에 비례하는 선형 로그 시간 복잡도 O(N logN)를 가지게 된다. 이렇게 해서 큰 입력에 대해서도 효율적으로 문제를..

Algorithm/백준 2023.06.14

[프로그래머스] N개의 최소공배수 with C++

문제 설명 제한 사항 및 입출력 예제 개념 최소 공배수의 개념을 유클리드 호제법을 이용하여 구하는 문제다. 백준 최소 공배수 문제의 연장선으로서, 주어진 벡터의 모든 원소를 순회하며 최소 공배수를 구하면 된다. 풀이 (1) 유클리드 호제법 구현 #include using namespace std; int gcd(int x, int y) { if (y == 0) return x; return gcd(y, x % y); } int lcm(int x, int y) { return x * y / gcd(x, y); } int solution(vector v) { int answer = 1; for (int i = 0; i < v.size(); ++i) answer = lcm(answer, v[i]); retur..

[프로그래머스] 예상 대진표 with C++

문제 설명 제한 사항 및 입출력 예제 개념 다음 그림처럼 토너먼트 브라켓 구조를 띄고 있는 대회에서 A참가자와 B참가자가 무조건 이긴다는 가정 하에 몇 번째 라운드에서 만날지 예측하는 문제다. 배열을 갱신하며 두 특정 참가자가 만나는 시점까지 반복하는 방법과, 두 참가자의 위치를 업데이트하고, 이들이 같아질 때까지 라운드를 증가시키는 방법이 존재한다. 풀이 (1) 배열 갱신 #include using namespace std; int solution(int n, int a, int b) { int cnt = 1; vector v(n, 0), tmp; v[a - 1] = true; v[b - 1] = true; for (int i = 0; i < n; i += 2) { if (v[i] && v[i + 1]..

[백준] 13305 주유소 with C++

문제설명 입출력 예제 개념 최소 비용을 통해 목표를 달성하는 그리드 알고리즘을 활용하는 문제다. 이 문제의 핵심 아이디어는 가장 낮은 기름값을 갖는 주유소를 찾아, 그곳에서 기름을 충전하는 것이다. 따라서 현재 위치에서 다음 도시로 이동하기 위해 필요한 기름을 충전하는데, 현재 주유소의 기름 가격과 다음 주유소의 기름 가격을 비교하여 최소 비용을 항상 유지하게 기름값을 갱신하면 된다. 풀이 #include #include using namespace std; int main() { long long N; cin >> N; vector station(N), road(N-1); for (int i = 0; i > road[i]; for (int i = 0; i < N; ++..

Algorithm/백준 2023.06.11

[백준] 11399 ATM with C++

문제설명 입출력 예제 개념 각 사람이 돈을 인출하는 데 필요한 시간 합의 최솟값을 출력하는 문제다. 대표적인 그리디 알고리즘으로 효율적으로 해결할 수 있는 문제로서, 실행 시간이 가장 짧은 프로세스부터 우선적으로 처리하는 최단 작업 우선 스케줄링 방식을 이용하면 된다. 여기서 돈을 인출하는데 걸리는 시간을 작업으로 보고, 이 작업들을 가장 짧은 것부터 처리하면 모든 사람이 돈을 인출하는데 필요한 최소 시간을 구할 수 있다. 풀이 #include #include #include using namespace std; int main() { int N; cin >> N; vector v(N); int* sum = new int[N]; for (int i = 0; i > v[i]; s..

Algorithm/백준 2023.06.10

[백준] 1931 회의실 배정 with C++

문제설명 입출력 예제 개념 이 문제는 회의 시간이 겹치지 않도록 하면서 동시에 가능한 한 많은 수의 회의를 배정하는 문제다. 이를 해결하는 방법 중 하나는 먼저 회의들을 종료 시간 기준으로 오름차순 정렬하는 것이다. 그리고, 가장 먼저 끝나는 회의를 선택한 후, 이전에 선택한 회의와 시간이 겹치지 않는 회의 중 가장 빨리 끝나는 회의를 다음으로 선택하는 것이다. 이러한 방식을 반복함으로써 가능한 많은 수의 회의를 배정할 수 있다. 풀이 #include #include #include using namespace std; int main() { int N, n, k, count = 1; cin >> N; vector v(N); 회의의 수 N, 그리고 회의의 시작과 끝에 대한 입력을 초기화할 변수 n, k,..

Algorithm/백준 2023.06.09

[백준] 11047 동전 0 wtih C++

문제설명 입출력 예제 개념 K원을 만드는데 필요한 최소한의 동전 개수를 구하는 문제다. 가장 가치가 큰 동전부터 사용하는 것이 최선의 서택이므로, 이러한 선택을 통해 가장 적은 동전을 사용하여 주어진 금액을 만들 수 있는 최적의 해답을 찾을 수 있다. 즉, 그리디 알고리즘을 사용하여 문제를 효율적으로 풀 수 있다. 풀이 #include #include using namespace std; int main() { int N, K, n, answer = 0; cin >> N >> K; vector v(N); for (int i = 0; i > v[i]; for (auto it = v.rbegin(); it != v.rend(); ++it) { if (*it < K) { answer..

Algorithm/백준 2023.06.08

[프로그래머스] 구명보트 with C++

문제 설명 제한 사항 및 입출력 예제 개념 이 문제는 최대 2명만 탑승 가능한 구명보트를 최소한으로 사용해 모든 사람을 구조하는 문제다. 이러한 상황에서 구명보트의 수를 최소화하려면, 남은 사람들 중 가장 가벼운 사람과 가장 무거운 사람을 동시에 태울 수 있는지 확인하면 된다. 따라서 투 포인터 알고리즘을 이용하여, 매 순간 보트에 최대한 많은 사람을 태우는 그리디 알고리즘을 구현하면 문제를 해결할 수 있다. 가장 가벼운 사람과 가장 무거운 사람이 보트의 무게 제한 내에 함께 탈 수 있다면, 두 사람을 동시에 태우는 것이 최선의 선택 그렇지 않다면, 가장 무거운 사람만 보트에 태우는 것이 최선의 선택 풀이 #include #include using namespace std; int solution(vec..

[프로그래머스] 영어 끝말잇기 with C++

문제 설명 제한 사항 및 입출력 예제 개념 이 문제는 끝말잇기 게임의 참가자들 중에서 규칙을 어긴 첫 번째 참가자와 그 참가자의 턴을 식별하고 출력하는 것을 목표로 한다. 여기서 주요 과제는 두 가지다. 각 턴에서 주어진 단어가 이전 단어의 마지막 글자로 시작하는지 판별 각 턴에서 주어진 단어가 이전에 사용된 적 있는 단어인지 확인 첫 번째 규칙은 문자열의 마지막 문자와 첫 문자를 비교하는 방식으로 해결할 수 있고, 두 번째 규칙은 find() 함수를 이용하여 단어의 이력을 관리하는 데이터 구조를 검색함으로써 해결할 수 있다. 이 두 가지 체크를 통과하지 못하는 첫 번째 단어를 발견하면, 해당 단어를 말한 참가자의 번호와 차례를 리턴하게 하면 된다. 풀이 #include #include #include ..