1. 1. FATB (하)
목적 : 언어 활용 능력 검증
정해 : O(1), O(N)
이론 : 등차수열의 합, 구현
해답 1, O(1)
1.Read A, B
2.Res B*(B+1)/2
3.Res Res – (A-1)*A/2
4.Print Res
해답 2, O(N)
1.Read A, B
2.Res 0
3.Res Res loop index from A to B
4.Print Res
2. 2. 러브 트라이앵글 (하)
목적 : 언어 활용 능력 검증, 규칙 분석 능력
정해 : O(𝑁2
)
이론 : 파스칼 삼각형(DP), 구현
본 문제는 평소 쉽게 접했던 러브 트라이앵글이 가지는 규칙을 찾고
이를 분석하는 문제입니다. 반면 단순 구현으로도 구현할 수 있습니다.
김 김 철 영 수 희
5 5 8 5 4 5
0 3 3 9 9
3 6 2 8
9 8 0
7 8
3. 2. 러브 트라이앵글(하)
위의 김철수, 김영희의 러브 트라이앵글을 보면, 각 글자들이 다음 행
을 구성할 때 얼마나 많은 영향을 주는지 판단 할 수 있습니다.
김 김 철 영 수 희
5 5 8 5 4 5
5+5 5+8 5+3 5+4 4+5
5+5+5+8 5+8+5+3 5+3+5+4 5+4+4+5
.
.
위의 경우를 마지막 행까지 계산해보면,
5(김) * 1 + 5(김) * 4 + 8(철) * 6 + 5(영) * 4 + 4(수) * 1 => 97%10 = 7
5(김) * 1 + 8(철) * 4 + 5(영) * 6 + 4(수) * 4 + 5(희) * 1 => 88%10 = 8 이며,
이는 파스칼 삼각형의 5행의 원소들의 곱의 합과 같습니다.
따라서 이 문제는 파스칼 삼각형을 동적 계획법으로 선 계산 후, 입력 크기 N-1행을
곱한 합을 출력하는 방식으로 해결 할 수 있습니다.
4. 2. 러브 트라이앵글(하)
구현 솔루션 )
A <- Integer [N][N]
Read A[0][0~N]
loop index idx from 1 to N-1
loop index jdx from 1 to N
A [ idx ] A[idx-1][jdx-1]+A[idx-1][jdx]
A[N-2][0] <- Reminder of A[N-2][0] divided by 10
A[N-2][1] <- Reminder of A[N-2][1] divided by 10
print A[N-2][0~1]
5. 3. 배열 연산 (하)
목적 : 언어 활용 능력 검증, 구현
정해 : O(𝑁𝑀), 구현
이론 : shift, reverse
위의 문제는 컴퓨터 공학 기초 이론인 Shift연산을 응용한 문제입니다.
주어지는 입력은 N개의 배열이며, M개의 연산 종류를 수행하고 결과
를 출력하는 문제입니다.
각 연산에 대한 쿼리는 연산 번호, 시작 인덱스와 종료 인덱스로 구성
됩니다.
6. 4. 무지개 퍼즐 (하)
- 구현, 그리디, 탐색
- 먼저 7개의 돌이 게임판에 올라갈 자리를 골라놨다고 생각해 봅시다.
그 때는 길이가 7인 두 수열의 곱을 최대화하는 문제로 바꿔 생각할
수 있습니다. 모든 경우에 대해서 계산하여 구할 수 있지만, 두 수열을
각각 정렬하여 곱하면 최대값을 구할 수 있습니다.
- 7개의 돌이 인접하지 않은 경우는 4가지가 있습니다. 이에 대한 예외
처리가 필요합니다.
7. K = 1 일때, 수평선 상 개구리에게서 가장 가까운 동굴을 찾아야합니다.
따라서 O(𝑎 log 𝑏)으로 이진탐색을 하면 쉽게 가장 가까운 동굴을 찾을 수 있습니다.
5. 개구리 (중)
8. K > 1 일때의 경우를 생각해봅시다.
𝑎𝑖 에 대한 가장 가까운 동굴을 찾으려면,
𝑎𝑖 % 𝐾 == 𝑏𝑗 % 𝐾 인 동굴들 중에서 이진탐색을 하면 됩니다.
따라서 𝑏𝑗를 list 𝑎𝑟𝑟 K 를 만들고, arr[𝑏𝑗 % 𝐾]에 𝑏𝑗를 push_back 합니다.
그 후, 차후에 할 이진탐색을 위해 각 배열을 정렬합니다.
𝑎𝑖 에서 동굴을 찾을 때, 𝑎𝑟𝑟[𝑎𝑖 % 𝐾] 에서 𝑎𝑖값을 이진탐색으로 찾으면 됩니다.
정리하면, 공간복잡도 O(𝑏), 시간복잡도 O(a log b)이고, 이진탐색을 하면 가장 가까
운 동굴을 찾을 수 있습니다. 또한, 답이 32bit integer를 초과할 수 있으므로, C++
의 경우 long long을 사용하여야 합니다.
5. 개구리 (중)
9. 다른 풀이로는 다익스트라를 사용하는 풀이를 떠올릴 수 있습니다.
일단 다익스트라의 최단경로 알고리즘을 돌려서 답을 얻을 수 있도록 그래프를 모델링해야
하는데, 그 방법은 다음과 같습니다.
1. 개구리와 굴을 정점으로 생각하고 위치를 k로 나눈 나머지가 같은 것들끼리 모읍니다.
2. 모은 것들을 정렬합니다.
3. 정렬된 배열에서 인접한 것들 사이에 비용이 둘의 위치 차이인 양방향 간선을 연결해줍니다.
4. 가상의 정점을 하나 만들고, 그 정점에서 모든 굴로 가는 간선을 하나씩 만들어 줍니다. 간선
의 비용은 0으로 줍니다.
5. 이제 가상의 정점을 시작점으로 하여 다익스트라의 최단경로 알고리즘을 돌립니다.
위 순서대로 진행한 뒤에, 답은 모든 개구리로 가는 최단거리의 합이 됩니다.
시간복잡도는 O(nlogn) 정도로 생각할 수 있습니다.
5. 개구리 (중)
10. 6. 가스레인지 (중)
- 최단경로, 탐색
파괴되지 않은 도로를 비용이 0인 간선, 파괴된 도로를 비
용이 1인 간선으로 생각하여, 최단경로를 구하면 답을 찾을
수 있습니다.
일반적으로 다익스트라 알고리즘을 사용하면 풀 수 있고,
특수한 형태의 BFS를 사용해도 됩니다.
m = a + b 라 하면, 다익스트라 알고리즘으로 O(mlogn)
의 시간복잡도로 풀 수 있고, BFS를 사용하면 O(n + m)의
시간복잡도로 풀 수 있습니다.
11. 이 문제는 하나의 차원을 낮게 생각하면 쉽게 해결할 수 있습니다.
1차원 배열에 임의의 숫자 𝑎𝑖가 있고,
우리가 구해야 하는 한 배열 𝑏가 있습니다
어떤 𝑏𝑖 중 임의의 위치와 크기의 𝑏 𝑚𝑎𝑥 가 있을 때,
𝑏𝑖 = 𝑏 𝑚𝑎𝑥 − 𝑎𝑏𝑠(𝑖 − max ) 라고 합니다.
모든 i에 대해, 𝑎𝑖 ≤ 𝑏𝑖를 만족하면서 가장 작은 𝑏 𝑚𝑎𝑥를 찾는 문제입니다.
𝑏 𝑚𝑎𝑥
7. 피라미드 (중)
12. 𝑏 𝑚𝑎𝑥
다음과 같은 배열이 주어지면, 기울기 1과 -1인 직선 둘을 이용하여
다음과 같이 해결할 수 있습니다.
7. 피라미드 (중)
13. 이 경우 dynamic programming으로 접근하면,
다음과 같이 테이블을 만들어 해결할 수 있습니다.
dp[i][0] = max(a[i], dp[i-1][0] + 1)
dp[i][1] = max(a[i], dp[i+1][1] + 1)
ans = min(ans, max(dp[i][0], dp[i][1]));
다시 본 문제로 넘어가 기울기에 대해 생각해보면,
다음 그림처럼 표현할 수 있습니다.
7. 피라미드 (중)
14. 그렇다면, 다음과 같은 네 가지의 dp 테이블을 생각할 수 있습니다.
이것을 식으로 표현하면,
dp[i][j][0] = max(a[i][j], max(dp[i + 1][j - 1][0], max(dp[i][j - 1][0], dp[i - 1][j - 1][0])) + 1)
dp[i][j][1] = max(a[i][j], max(dp[i - 1][j - 1][0], max(dp[i - 1][j][0], dp[i - 1][j + 1][0])) + 1)
dp[i][j][2] = max(a[i][j], max(dp[i - 1][j + 1][0], max(dp[i][j + 1][0], dp[i + 1][j + 1][0])) + 1)
dp[i][j][3] = max(a[i][j], max(dp[i + 1][j - 1][0], max(dp[i + 1][j][0], dp[i + 1][j + 1][0])) + 1)
가 됩니다. 각 테이블을 적당히 순서에 맞게 채우고,
ans = max(dp[i][j][0], dp[i][j][1], dp[i][j][2], dp[i][j][3]) 으로 답을 구하면 됩니다.
7. 피라미드 (중)
15. 또한 네 방향의 기울기를 이용하여,
3차원 상의 평면을 나타내는 함수 네 개로 해결할 수 있습니다.
이 풀이법은 문제를 쉽게 풀 수 있지만,
의도하지 않은 방법이므로 설명하지 않습니다.
7. 피라미드 (중)
16. 8. 최소공배수 (중)
- 수학, 정수론
- 두 수의 최소공배수는 두 수의 공통소인수들을 모두 곱하되, 지수의 최대값만
취하여 곱하면 구할 수 있습니다. 따라서 각각의 수들을 소인수분해하여 소수
의 개수만 저장해 놓는다면, 곱해지고 난 뒤의 수의 최소공배수를 구할 수 있
습니다.
- 에라토스테네스의 체를 응용하여 소인수분해를 하거나, 주어진 수의 제곱근
까지만 나눠보는 방법으로 소인수분해를 빠르게 할 필요가 있습니다.
- 또한, 이 문제에서는 최종적으로 구해지는 소수들의 개수가 매우 크므로, 빠
른 거듭제곱 알고리즘을 사용하여 곱해야 합니다.
- 주어지는 수의 범위가 m 이라고 하면 시간복잡도는 O(nlogm) 정도가 됩니다.
a 2^3 5^2 200
b 3^2 5^3 1125
LCM(a,b) 2^3 3^2 5^3 9000