반응형

백준 10757번 문제입니다. (solved.ac) 기준 브론즈 5문제입니다...만 특정 언어들 기준으로는 실버정도 되는 것 같습니다https://www.acmicpc.net/problem/10757

 

10757번: 큰 수 A+B

두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.

www.acmicpc.net

문제

문제 접근

A + B를 출력하는 간한단 문제이지만 각 수의 최댓값이 10^10000-1이기 때문에 Long의 범위도 아득히 벗어나게 됩니다...

파이썬은 그냥 A + B를 출력하면되고 Java와 Kotlin은 BigInteger를 사용하여 무한대의 정수 계산을 할 수 있지만 이렇게 편리하게 풀 수 없는 언어들도 있어 이를 대비하여 문자열로 더하기를 구현해보았습니다

 

우선은 A, B(이하 a, b)를 문자열로 입력 받습니다. 맨 뒷자리(일의 자리)에서부터 계산을 해야하기 때문에 reversed()함수를 사용하여 뒤집어서 받아줍니다. ex) 12345, 7896 -> a = 54321, b = 6987 
a의 문자들을 하나씩 탐색하고 b와 더해줄 것입니다. 하지만 b의 길이가 더 긴 경우도 있을 수 있기 때문에 b의 길이가 더 길다면 a와 b를 교체해줍니다.(무조건 길이가긴 문자열이 담길 a를 기준으로 탐색할 것임)

 

a를 forEachIndexed를 사용하여 순차탐색 해줍니다. 탐색중인 Index가 b의 길이보다 클 경우 b에 index로 접근하면 범위 오류가 발생하기 때문에 if문을 사용하여 조건을 걸어주었습니다.

 

12345, 7896을 입력받았다는 가정하에 문제를 설명하겠습니다.

index = 0 일때 a = '5', b = '6'입니다. 이를 정수로 변환 후 더하면 11이 되기 때문에 다음 자릿수에 올림처리가 필요합니다. 다음 자릿수에 올림 처리를 하기 위하여 isAdd = true로 만들어줍니다. isAdd가 true라면 올림처리를 해주어야한다는 뜻입니다. 올림처리를 해주었기 때문에 11은 1의 자리만 남기도록 10으로 나눈 나머지로 만들어줍니다. 일의 자리는 1로 계산이 됩니다.

 

index = 1 일때 a = '4', b = '9'입니다. isAdd가 true이므로 올림처리를 진행하여 a + b는 14가 됩니다. 진행 후 isAdd는 false로 만들어줍니다. 하지만 a + b가 9보다 크기때문에 이전과 마찬가지로 다음 자릿수에 올림처리(isAdd=true)를 해주고 현재 자릿수의 값은 10으로 나눈 나머지를 사용하여 십의 자리는 4로 계산이 됩니다.

 

index = 2 일때 a = '3', b = '8'입니다. 마찬가지로 올림처리를 진행하면 12가되고 이전의 과정과 동일한 과정을 거친 후 백의 자리는 2로 계산이 됩니다.

 

index = 3 일때 a = '2', b = '7'입니다. 마찬가지로 올림처리를 진행하면 10이되고 이전의 과정과 동일한 과정을 거친 후 천의 자리는 0으로 계산이 됩니다.

 

마지막 인덱스인 index = 4 일때 a = '1', b는 존재하지 않습니다. 현재 isAdd는 true이기 때문에 현재 자릿수는 2가됩니다. 따라서 만의 자리는 2가 됩니다.

 

해당 문자들을 순차적으로 더하면 12345 + 7896 = 20241과 동일한 정답이 나오게 됩니다.

정답 코드 (BigInteger 사용)

fun main(){
    val (a, b) = readln().split(" ").map { it.toBigInteger() }
    println(a.add(b))
}

정답 코드 (문자열로 더하기를 구현)

fun main() {

    var ans = ""
    // 올림여부
    var isAdd = false
    var (a, b) = readln().split(" ")

    // 계산을 뒤에서부터 할 것임.
    a = a.reversed()
    b = b.reversed()

    // 무조건 a가 길게 만들것.
    if (b.length > a.length) {
        var temp = a
        a = b
        b = temp
    }

    a.forEachIndexed { index, it ->

        val aNum = it - '0'

        // b의 길이가 현재 탐색중인 index보다 클때만
        if (b.length > index) {
            val bNum = b[index] - '0'
            // 올림처리 후 isAdd = false로
            var curNum = aNum + bNum + if (isAdd) 1 else 0
            isAdd = false
            
            // 다음 자릿수에 올림이 필요한 경우
            if (curNum > 9) {
                curNum %= 10
                isAdd = true
            }
            ans = curNum.toString() + ans
        } else {
            if (isAdd) {
                // 올림처리 후 isAdd = false로
                var curNum = aNum + 1
                isAdd = false
                // 다음 자릿수에 올림이 필요한 경우
                if (curNum > 9) {
                    curNum %= 10
                    isAdd = true
                }
                ans = (curNum).toString() + ans

            } else {
                ans = it + ans
            }

        }

    }
    
    // 마지막 자릿수에서 올림이 필요한 경우 맨 앞에 1이 추가되어야함.
    if (isAdd) ans = "1" + ans

    println(ans)
}

 

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기