[문제]
A, B 두 사람이 볼링을 치고 있습니다. 두 사람은 서로 무게가 다른 볼링공을 고르려고 합니다. 볼링공은 총 N개가 있으며 각 볼링공마다 무게가 적혀 있고, 공의 번호는 1번 부터 순서대로 부여됩니다. 또한 같은 무게의 공이 여러개 있을 수 있지만, 서로 다른 공으로 간주합니다. 볼링공의 무게는 1부터 M까지의 자연수 형태로 존재합니다.
예를 들어 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가지입니다. N개의 공의 무게가 각각 주어질 때, 두 사람이 볼링공을 고르는 경우의 수를 구하는 프로그램을 작성하세요.
[입력 조건]
- 첫째 줄에 볼링공의 개수 N, 공의 최대 무게 M이 공백으로 구분되어 각각 자연수 형태로 주어집니다. (1 ≤ N ≤ 1,000, 1 ≤ M ≤ 10)
- 둘째 줄에 각 볼링공의 무게 K가 공백으로 구분되어 순서대로 자연수 형태로 주어집니다. (1 ≤ K ≤ M)
[출력 조건]
- 첫째 줄에 두 사람이 볼링공을 고르는 경우의 수를 출력합니다.
- 첫째 줄에 볼링공의 개수 N, 공의 최대 무게 M이 공백으로 구분되어 각각 자연수 형태로 주어집니다. (1 ≤ N ≤ 1,000, 1 ≤ M ≤ 10)
- 둘째 줄에 각 볼링공의 무게 K가 공백으로 구분되어 순서대로 자연수 형태로 주어집니다. (1 ≤ K ≤ M)
내가 해결한 방법
import java.io.BufferedReader
import java.io.InputStreamReader
import java.util.*
fun main(){
val br = BufferedReader(InputStreamReader(System.`in`))
val stk = StringTokenizer(br.readLine())
val n = stk.nextToken().toInt() // 볼링공의 개수
val m = stk.nextToken().toInt() // 볼링공의 최대 무게
val weightList = br.readLine().split(" ").map{ it.toInt() } // 볼링공 무게의 리스트
var result = n * (n - 1) / 2 // 무게가 같은 볼링공 포함 경우의 수
for(weight in weightList.toSet()){ // 중복제거 요소 순환
val equalCount = weightList.count { it == weight }
result -= equalCount * (equalCount - 1) / 2 // 무게가 같은 볼링공 제거
}
print(result)
}
내가 푼 방법은 조합을 생각했다. 전체의 경우(N)에서 2가지를 뽑는 경우의 수 는 N * (N-1) / 2이다. 또한 무게가 같은 볼링공의 개수가 EC일때 같은 무게를 빼는 경우의 수도 EC * (EC - 1) / 2이다. 해당 풀이로 테스트 케이스는 통과했지만, 문제에서 제시한 최대 무게는 사용하지 않았다.
책의 풀이를 참고한 방법
import java.io.BufferedReader
import java.io.InputStreamReader
import java.util.*
fun main(){
val br = BufferedReader(InputStreamReader(System.`in`))
val stk = StringTokenizer(br.readLine())
var n = stk.nextToken().toInt() // 볼링공의 개수
val m = stk.nextToken().toInt() // 볼링공의 최대 무게
val weightArray = IntArray(11)
br.readLine().split(" ").forEach{
weightArray[it.toInt()] += 1
} // 볼링공 무게의 리스트
var result = 0
repeat(m){
n -= weightArray[it] // 전체 개수 중 중복 제거
result += weightArray[it] * n // 선택할 수 있는 경우의 수 * 동일한 무게의 볼링공의 수
}
print(result)
}
무게마다 볼링공이 몇개 있는지 먼저 계산을 하여 배열에 값을 추가하고, 최댓값 만큼 반복하여 계산할 수 있다.
단계가 지날 때 마다 동일한 무게의 볼링공의 수 와 이전에 계산했던 경우를 제외하고 곱하여 계산한다.
https://github.com/jeongjaino/Problem_solving/blob/master/src/main/kotlin/day1/Ch11_5.kt
GitHub - jeongjaino/Problem_solving: 겨울방학 알고리즘 스터디!
겨울방학 알고리즘 스터디! . Contribute to jeongjaino/Problem_solving development by creating an account on GitHub.
github.com