본문 바로가기
  • 개발하는 곰돌이
Algorithm/BOJ

[Kotlin] 백준 11387 : 님 무기가 좀 나쁘시네여

by 개발하는 곰돌이 2022. 12. 15.

문제 링크

 

11387번: 님 무기가 좀 나쁘시네여

각 줄마다 "공격력", "힘", "치명타 확률", "치명타 피해비율", "공격속도 증가"의 수치를 나타내는 다섯 개의 정수가 공백을 사이에 두고 순서대로 주어진다. 첫 번째 줄은 무기를 장착한 크리의

www.acmicpc.net



문제 해설

문제 자체는 단순한 구현 문제지만 주의할 점이 있다. 전투력을 계산할 때 실수 계산을 많이 하게 되는데 컴퓨터는 내부적으로 모든 수를 2진법으로 저장하기 때문에 소수점 이하 부분은 정확하게 저장할 수 없고 근사치를 저장하게 된다. 이 과정에서 여러번의 연산을 하다보니 오차가 발생하여 식은 맞지만 답은 틀리는 경우가 발생할 수 있다. 따라서 BigDecimal을 사용하여 오차 없이 계산해야 한다. 이점만 주의하면 크리와 파부의 기존 전투력과 무기를 바꿨을 때의 전투력을 비교하여 결과를 출력하면 된다.


Code

import java.math.BigDecimal
import java.util.StringTokenizer

fun main() = with(System.`in`.bufferedReader()) {
    val players = Array(2) {
        readLine().let {
            StringTokenizer(it).run {
                Player(
                    BigDecimal(nextToken()),
                    BigDecimal(nextToken()),
                    BigDecimal(nextToken()).divide(100.toBigDecimal()),
                    BigDecimal(nextToken()).divide(100.toBigDecimal()),
                    BigDecimal(nextToken()).divide(100.toBigDecimal())
                )
            }
        }
    }
    val weapons = Array(2) {
        readLine().let {
            StringTokenizer(it).run {
                Player(
                    BigDecimal(nextToken()),
                    BigDecimal(nextToken()),
                    BigDecimal(nextToken()).divide(100.toBigDecimal()),
                    BigDecimal(nextToken()).divide(100.toBigDecimal()),
                    BigDecimal(nextToken()).divide(100.toBigDecimal()))
            }
        }
    }
    println(
        if ((players[0] - weapons[0] + weapons[1]).power > players[0].power) '+'
        else if ((players[0] - weapons[0] + weapons[1]).power < players[0].power) '-'
        else '0'
    )
    println(
        if ((players[1] - weapons[1] + weapons[0]).power > players[1].power) '+'
        else if ((players[1] - weapons[1] + weapons[0]).power < players[1].power) '-'
        else '0'
    )
}

class Player(var attack: BigDecimal, 
             var strength: BigDecimal, 
             var critical: BigDecimal, 
             var criticalDamage: BigDecimal, 
             var attackSpeed: BigDecimal) {
    val power
        get() = attack * 
                (1.toBigDecimal() + strength.divide(100.toBigDecimal())) * 
                ((1.toBigDecimal() - minOf(BigDecimal(1), critical)) + minOf(BigDecimal(1), critical) * criticalDamage) * 
                (1.toBigDecimal() + attackSpeed)

    operator fun plus(other: Player) = Player(
        this.attack + other.attack,
        this.strength + other.strength,
        this.critical + other.critical,
        this.criticalDamage + other.criticalDamage,
        this.attackSpeed + other.attackSpeed)

    operator fun minus(other: Player) = Player(
        this.attack - other.attack,
        this.strength - other.strength,
        this.critical - other.critical,
        this.criticalDamage - other.criticalDamage,
        this.attackSpeed - other.attackSpeed)
}

댓글