PS(Problem Solving)/BOJ

[백준/BOJ] 13251번: 조약돌 꺼내기

JunsuKim 2022. 3. 3.
728x90

https://www.acmicpc.net/problem/13251

 

13251번: 조약돌 꺼내기

첫째 줄에 뽑은 조약돌이 모두 같은 색일 확률을 출력한다. 정답과의 절대/상대 오차는 10-9까지 허용한다.

www.acmicpc.net

문제

효빈이의 비밀 박스에는 조약돌이 N개 들어있다. 조약돌의 색상은 1부터 M까지 중의 하나이다.

비밀 박스에서 조약돌을 랜덤하게 K개 뽑았을 때, 뽑은 조약돌이 모두 같은 색일 확률을 구하는 프로그램을 작성하시오. 

입력

첫째 줄에 M (1 ≤ M ≤ 50)이 주어진다.

둘째 줄에는 각 색상의 조약돌이 몇 개 있는지 주어진다. 각 색상의 조약돌 개수는 1보다 크거나 같고 50보다 작거나 같은 자연수이다.

셋째 줄에는 K가 주어진다. (1 ≤ K ≤ N)

출력

첫째 줄에 뽑은 조약돌이 모두 같은 색일 확률을 출력한다. 정답과의 절대/상대 오차는 10-9까지 허용한다.

해설

조약돌을 뽑았을 때 모두 같은 색일 확률을 구하면 되는 문제이다.조합을 이용할 경우 일정 이상이 되면 값이 너무 커져 BigInteger를 사용해야한다.다른 방법으로는 그냥 계산을 통해 특정 돌만 나올 경우를 구해 각각의 확률들을 더해주면 된다.

 

예제 입력 3을 예시로 들면35 6 72가 있다.이 때 총 돌의 개수는 5 + 6 + 7인 18이 되고,이 중 첫번째 돌만 나올 확률은 5/18 * 4/17 * 3/16이 된다.

 

이처럼 각각의 돌만 나올 확률을 구해 다 더해주면 같은 돌만 나올 확률을 구할 수 있다.

소스 코드

import java.util.*

fun main()  = with(System.`in`.bufferedReader()) {
    val m = readLine().toInt()
    val colorRock = IntArray(m)
    val percentage = DoubleArray(m)
    val st = StringTokenizer(readLine())
    var totalRock = 0
    repeat(m) { i ->
        colorRock[i] = st.nextToken().toInt()
        totalRock += colorRock[i]
    }
    val k = readLine().toInt()

    for(i in 0 until m) {
        if(colorRock[i] < k) continue
        var savePercentage = 1.0
        for(j in 0 until k) {
            savePercentage *= (colorRock[i] - j).toDouble() / (totalRock - j).toDouble()
        }
        percentage[i] = savePercentage
    }
    var ans = 0.0
    repeat(m) { i -> ans += percentage[i] }
    println(ans)
}
728x90

댓글