Skip to content

Commit e5e087c

Browse files
authored
Merge pull request #220 from AlgorithmStudy-Allumbus/YoonYn9915
YoonYn9915/ 6월 1주차/ 3문제
2 parents 17cd42b + a96d456 commit e5e087c

3 files changed

Lines changed: 125 additions & 0 deletions
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'''
2+
요구사항
3+
1. 매우 많은 숫자 카드 묶음이 책상 위에 놓여 있다. 이들을 두 묶음씩 골라 서로 합쳐나갈 때, 최소한 몇 번의 비교가 필요한지를 계산
4+
5+
1. 아이디어
6+
- A개, B개 두 묶음의 카드를 비교하는데 A+B번 비교해야 함.
7+
- 비교한 횟수를 누적시켜 최소값을 찾아야 하므로 비교횟수가 가장 작은 것들부터 시작해야 함.
8+
- A, B, C 3개의 카드 묶음이 있고 A < B < C라면, (A+B) + ((A+B) + C)가 최소값이다.
9+
10+
2. 시간복잡도
11+
- (1 ≤ N ≤ 100,000)
12+
- O(N + (N-1) * logN), 대략 O(NlogN)으로 시간복잡도 만족.
13+
14+
3. 구현
15+
3.1 입력받기
16+
3.2 카드 묶음 정렬(우선순위 큐에 저장)
17+
3.3 가장 카드가 적은 묶음 2개를 뽑아 더한 값을 정답변수에 누적시키고 다시 우선순위큐에 저장
18+
3.4 우선순위 큐가 하나 남을때까지 반복
19+
3.5 정답 출력
20+
'''
21+
22+
import sys
23+
import heapq
24+
25+
inp = sys.stdin.readline
26+
27+
N = int(inp().strip())
28+
arr = []
29+
answer = 0
30+
31+
for _ in range(N):
32+
arr.append(int(inp().strip()))
33+
34+
# 매번 최소 카드 묶음 2개를 뽑기 위해 heap 사용
35+
heapq.heapify(arr)
36+
37+
while len(arr) > 1:
38+
min1 = heapq.heappop(arr)
39+
min2 = heapq.heappop(arr)
40+
41+
answer += min1 + min2
42+
heapq.heappush(arr, min1 + min2)
43+
44+
print(answer)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
def dfs(x, y):
3+
if graph[x][y] == '-':
4+
graph[x][y] = 1
5+
for _y in [1, -1]:
6+
Y = y + _y
7+
if (Y > 0 and Y < m) and graph[x][Y] == '-':
8+
dfs(x, Y)
9+
if graph[x][y] == '|':
10+
graph[x][y] = 1
11+
for _x in [1, -1]:
12+
X = x + _x
13+
if (X > 0 and X < n) and graph[X][y] == '|':
14+
dfs(X, y)
15+
16+
17+
n, m = map(int, input().split())
18+
graph = []
19+
for _ in range(n):
20+
graph.append(list(input()))
21+
22+
count = 0
23+
for i in range(n):
24+
for j in range(m):
25+
if graph[i][j] == '-' or graph[i][j] == '|':
26+
dfs(i, j)
27+
count += 1
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
'''
2+
요구사항
3+
1. A만큼의 에너지를 가진 슬라임과 B만큼의 에너지를 가진 슬라임을 합성하려면 A × B 만큼의 에너지 필요.
4+
2. N마리의 슬라임들을 적절히 합성해서 1마리의 슬라임으로 만들때, 필요한 에너지 값을 모두 곱한 값을 최소로 만든다.
5+
3. 슬라임을 모두 합성했을 때 청구될 비용의 최솟값을 1, 000, 000, 007로 나눈 나머지를 출력한다. 에너지가 전혀 필요하지 않은 경우엔 1 을 출력한다.
6+
7+
1. 아이디어
8+
곱의 누적곱이 최소가 되게 하려면 곱셈의 결과가 최소가 나오게 해야 함. 즉 큰 수를 가장 적게 곱하고
9+
되도록 작은수 X 작은수 형태로 풀이. 따라서 각 경우마다 가장 작은 두 수를 그리디하게 뽑아서 곱하고 누적곱해주면 된다.
10+
11+
2. 시간복잡도
12+
슬라임 수 N (1 ≤ N ≤ 60), i번째 슬라임의 에너지 Ci (2 ≤ Ci ≤ 2 × 1018)일때,
13+
모든 테스트 케이스에 대한 N 의 총합이 1, 000, 000을 넘지 않음으로 테스트 케이스의 수는 최대 500,000.
14+
즉 O(test_case * (N-1)) == O(500,000 * 59)로 만족.
15+
16+
3. 구현
17+
3-1. 입력받기
18+
3-2. N-1번 가장 작은 두 수를 뽑는다.
19+
3-3. 두 수를 곱하고 정답변수에 누적시킨다.
20+
3-4. 곱한 두 슬라임을 제거하고, 새 슬라임을 추가한다.
21+
3-5. 정답 출력
22+
23+
'''
24+
25+
26+
import heapq
27+
import sys
28+
29+
inp = sys.stdin.readline
30+
MOD = 1000000007
31+
32+
test_case = int(inp())
33+
34+
for _ in range(test_case):
35+
N = int(inp())
36+
arr = list(map(int, inp().split()))
37+
38+
if N == 1:
39+
print(1)
40+
continue
41+
42+
hq = []
43+
for num in arr:
44+
heapq.heappush(hq, num)
45+
46+
result = 1
47+
while len(hq) > 1:
48+
a = heapq.heappop(hq)
49+
b = heapq.heappop(hq)
50+
energy = a * b
51+
result = (result * energy) % MOD
52+
heapq.heappush(hq, energy)
53+
54+
print(result)

0 commit comments

Comments
 (0)