본문 바로가기

알고리즘, 자료구조/알고리즘29

17298 오큰수 일단 비교를 해야하니 담아둘 컨테이너가 필요하다. 배열을 백만개 선언할 수 도있고, 벡터를 이용할 수도 있지만, 간단하게 배열을 써보자. 그렇게 한다면, 최악의 경우 (제일 큰 숫자가 맨 오른쪽에 있는 경우) 탐색시간이 O(백만^2) 이 들어서 시간초과가 날 것이다. 스택에 하나씩 넣고 빼면서 비교해볼까 4 3 5 2 7 을 예로들면, stack 3 stack 3 5 들어간 5가 3보다 크므로 출력 stack 3 5 2 stack 3 5 2 7 들어간 7이 5보다 크므로 출력 들어간 7이 2보다 크므로 출력 7 다음에 들어간 것이 없으므로 -1 출력 .... 흠 무언가 의미가 다가오지 않는다. 이럴 때는 발상을 뒤집어 보자. 배열에 3 5 2 7을 넣어놓고, stack에 배열 끝 자리부터 거꾸로 담는다... 2019. 7. 14.
Greedy 알고리즘 11047가 동전 0 1. 예제 - { 1 5 10 50 100 500 1000 5000 10000 50000 } 이 있을 때, 4200원을 만드는 최소의 방법은 1000 * 4 + 100 * 2 이므로 총 6회이다. 2. 문제해결 - [그리디한 해결전략] 순간의 최적해를 구한다. (위 문제는 순간의 최적해가 최종 문제의 정답의 최적해인 경우라서 문제가 해결된다.) 가치가 가장 큰 동전을 최대한 많이 이용하고, 같은 방법으로 나머지 금액을 가치가 가장 큰 동전을 최대한 많이 이용해서 금액을 다 채울때 까지 반복한다. 2019. 7. 14.
1966 프린터 큐 queue를 만들고, 4 2 1 2 3 4 n = 4, m = 2, cnt = 0 2 3 4 1 m = 1 3 4 1 2 m = 0 4 1 2 3 m = 3 1 2 3 m = 2, cnt = 1 2 3 1 m = 1 3 1 2 m = 0 1 2 cnt = 2 6 0 1' 1 9 1 1 1 n = 6, m = 0, cnt = 0 1 9 1 1 1 1' m = 5 9 1 1 1 1' 1 m = 4 1 1 1 1' 1 m = 3, cnt = 1 1 1 1' 1 m = 2, cnt = 2 1 1' 1 m = 1, cnt = 3 1' 1 m = 0, cnt = 4 1 cnt = 5 max 값 있으면 max 값을 pop 할 때까지 front를 pop하고 push함 m 인덱스 갱신 cnt++ max 값 없으면 m 값.. 2019. 7. 1.
11729 하노이 탑 접근 장대 1, 2, 3이 있고, 1에 원판 3개가 있을 때, 이 원판을 모두 크기 순에 맞게 장대 3에 옮겨야 한다. 그 과정을 살펴보자. a b 는 a의 맨위의 원판을 b의 맨 위로 옮긴다는 뜻이다. 자 머리속으로 상상해보자. 그러면서 일반화 해보자.(n개의 원판으로!) 1 3 1 2 3 2 ---------- 1) 지금 이상황은 1에서 제일 큰 원판이, 2에 n-1개의 원판이 순서대로 있는 상황이다. 1 3 ---------- 2) 1에 있는 가장 큰 원판을 3으로 보낸다. 2 1 2 3 1 3 ---------- 3) 2에서 n-1개의 원판을 3으로 보내는 상황이다. 함수 f(a, b, n_disk)를 정의하고 맨처음 상황을 f(1, 3, 3)으로 생각해보자. 1)의 상황을 다시 한번 보자. f(.. 2019. 6. 28.
[백트래킹] 1987 알파벳 1. 알파벳 보드 b 생성 2. 알파벳 모음 alphabets 생성 - 이미 찾은 알파벳 확인용 3. 방향 설정 상 하 좌 우 dx = {-1, 1, 0, 0} dy = {0, 0, -1, 1} 이 보드의 (0, 0) 부터 시작해서, 상하좌우 매번 탐색하면서 - 보드의 바깥으로 가는 경우는 다시 돌아옴(백트랙). - 새로운 알파벳을 탐색했으면 기록하고, 다음 경로 탐색. - 이미 기록된 알파벳을 탐색했으면 백트랙. ex) 2 4 CAAB ADCB 이와 같은 알파벳 보드에서, 재귀함수가 어떻게 진행되는지 보자. C : 알파벳 체크. 1 상 : 없음, 돌아옴 2 하 : A 체크 2-1 상 : C가 이미 체크 되어있음, 돌아옴 2-2 하 : 없음, 돌아옴 2-3 좌 : 없음, 돌아옴 2-4 우 : D 체크 2.. 2019. 6. 27.
GCD algorithm GCD 알고리즘은 유클리드 호제법(Euclidean algorithm)으로도 불린다. 아래와 같은 원리를 이용하여 알고리즘을 짠다. a lemma: if a, b 가 정수이고 둘다 0이 아니면서 a = b*q + r을 만족하는 q, r 이 정수이면 then gcd(a, b) = gcd(b, r) 이를 코드에 그대로 옮기면, 최대공약수를 쉽게 구할 수 있다. 최소공배수는 A와 B를 곱하고, gcd(A, B)로 나누어 주면 구할 수 있다. 이를 이용하면 백준 문제를 쉽게 풀수있다. #include int main() { int a, b, r; scanf("%d %d", &a, &b); int A = a; int B = b; while (b != 0) { r = a % b; a = b; b = r; } pri.. 2019. 6. 11.
9251 LCS LCS 또한 교재에서 볼 수 있는 DP의 전형적인 문제이다. 길이가 각각 i, j인 문자열 x, y가 있다고 해보자. LCS(i, j) 는 문자열 x, y의 최장 공통 부분 수열(LCS)이라고 할 때, 다음과 같이 점화식을 세울 수 있다. LCS(i, j) = LCS(i-1, j-1) + 1 if x[i] == y[j] max( LCS(i-1, j), LCS(i, j-1) ) otherwise 이렇게 만들어놓고, i와 j에 따른 dynamic programming을 구현하기 위하여 d[i][j]를 만든다. 그리고 이 행렬을 잘 채워나가다가, 맨 마지막 오른쪽 부분 즉, d[i][j]가 우리가 원하는 LSC 값이다. #include #include #include using namespace std; in.. 2019. 6. 9.
2293 동전 1 Dynamic Programming의 전형적인 문제, - Optimal substructure - Memoization 알고리즘 문제에서, DP는 메모리와 시간을 아껴주는 도구이고 기존의 방법으로 풀기 껄끄러운 문제에 새로운 해결법을 제시해 주기도 한다. 수학적 기반은, 점화식(Recurrence relation) 1. 문제 파악 1, 2, 5가 주어질 때 10을 만들기 위해 몇 가지 조합으로 10을 만들 수 있는가. 1) 1원 * 10 2) 2원 * 5 3) 2원 * 4 + 1원 * 2 4) 2원 * 3 + 1원 * 4 5) 2원 * 2 + 1원 * 6 6) 2원 * 1 + 1원 * 8 7) 5원 * 2 8) 5원 * 1 + 1원 * 5 9) 5원 * 1 + 2원 * 1 + 1원 * 3 10) 5원 *.. 2019. 6. 9.
5639 이진검색트리 1. 문제분석 트리를 전위순회(preorder)한 결과가 주어질 때, 후위순회(postorder)한 결과를 출력한다. 1 2 3 있으면 전위순회(preorder) : 1 2 3 후위순회(postorder) : 2 3 1 중위순회(inorder) : 2 1 3 (참고) 아이디어 "preorder 입력이 주어지는데, 이 순서대로 이진검색트리(이하 BST)에 삽입하면 BST에 성질에 맞게 입력이 된다. 따라서 이 결과를 preorder로 출력하면 된다." 2. 시간, 메모리 분석 - "노드의 수 10,000개 이하" for each node i // O(N) BST_insert(i) // O(N) 따라서 O(N^2) = 10000 * 10000 = 1억 (1초) OK! - 256MB.... 각 node 1만개.. 2019. 6. 8.
728x90