본문 바로가기
연습

[그리디] 볼링공 고르기

by ybs 2021. 10. 11.
반응형

A, B 두 사람이 볼링을 치고 있다. 볼링공은 총 N개 있고 볼링공의 무게는 각각 다르며 1부터 M까지의 자연수 형태로 무게가 존재한다.(1 <= N <= 1000, 1 <= M <= 10) 같은 무게의 공이 여러개 있을 수 있고 서로 다른 공으로 간주한다. 예를 들어 N이 5이고 M이 3이며 각각의 무게가 차례대로 1, 3, 2, 3, 2 일 때 각 공의 번호가 차례대로 1번부터 5번 까지 부여된다. 이때 두 사람이 고를 수 있는 볼링공 번호의 조합을 구하면 다음과 같다.

 

(1번공, 2번공), (1번공, 3번공), (1번공, 4번공), (1번공, 5번공), (2번공, 3번공), (2번공, 5번공), (3번공, 4번공), (4번공, 5번공)

 

결과적으로 두 사람이 공을 고르는 경우의 수는 8가지다. 

 

위의 예에서 (1번공, 2번공) 이 선택 되었을 때, (2번공, 1번공) 은 선택되지 않는다. 같다고 보는것이다.

제일 먼저 생각난것은 이중 for문이었다. i 번째 인덱스의 값과 i+1부터 끝까지의 값을 전부 비교하면서 같지 않으면 count를 늘려가는 방식이다. 이중 for문이니 시간복잡도가 O(n^2) 로 안좋지만 볼링공 최대 갯수가 1000 개 이므로 괜찮다고 판단했다.

N, M = map(int, input().split())
data = list(map(int, input().split()))

count = 0
for i in range(0, int(N)):
	for j in range(i+1, int(N)):
		if data[i] != data[j]:
			count += 1

print(count)

 

하지만 이 방법은 N이 엄청 클 때는 적합한 알고리즘이 아니다. 아까 1, 3, 2, 3, 2 를 갖고 다른방법으로 풀어보자.  먼저 무게 마다 볼링공 갯수를 구한다.

w1 인 볼링공 : 1개

w2 인 볼링공 : 2개

w3 인 볼링공 : 2개

 

step1 : A가 w1 인 공을 선택할 때의 경우의 수는 1(w1인 공의 갯수) * 4(B가 선택하는 경우의 수) = 4 가지

step2 : A가 w2인 공을 선택할 때의 경우의 수는 2(w2인 공의 갯수) * 2(B가 선택하는 경우의 수) = 4 가지

step3 : A가 w3인 공을 선택할 때의 경우의 수는 2(w3인 공의 갯수) * 0(B가 선택하는 경우의 수) = 0 가지

 

따라서 총 8가지다.

n, m = map(int, input().split())
data = list(map(int, input().split()))

# 1부터 10 까지 무게를 담는 리스트
array = [0] * 11

# 각 무게에 해당하는 볼링공의 갯수 늘리기
for x in data:
	array[x] += 1

result = 0
# 1부터 m 까지의 각 무게에 대해 처리
for i in range(1, m+1):
	# 무게가 i 인 볼링공의 갯수(A가 선택할 수 있는 갯수) 제외
	# 즉 array[i] 만큼 빼진 n은 B가 선택하는 경우의 수다.
	n -= array[i]
	# 무게가 i 인 공의 갯수와 B가 선택하는 경우의 수 곱하기
	result += array[i] * n

print(result)

 

출처 : 이것이 코딩테스트다 나동빈 저

반응형

'연습' 카테고리의 다른 글

[그리디] 숫자 카드 게임  (2) 2021.10.24
[그리디] 무지의 먹방 라이브  (0) 2021.10.17
[그리디] 만들 수 없는 금액  (0) 2021.10.03
[그리디] 문자열 뒤집기  (0) 2021.09.26
[그리디] 모험가 길드  (0) 2021.09.23