자릿수의 합: 동률이면 더 큰 수 고르기

·설명 약 6분·작성: 해비·블로그 소개

자릿수의 합이 같은 자연수가 여러 개라면 어떤 수를 반환하나요?

N개의 자연수 중 자릿수의 합이 가장 큰 원래 수를 구합니다. 합이 같은 수가 여러 개라면 그중 가장 큰 수를 반환합니다. 자릿수의 합 자체를 반환하는 문제가 아닙니다.

적용 조건·범위: 별도로 만든 확인 입력 [235, 1234, 22]와 [1234, 235, 22]는 모두 1234를 골라야 합니다. 순서를 뒤집어도 동률 규칙은 바뀌지 않습니다. [10000000, 1000000, 1]처럼 합이 모두 1인 경우에는 10000000이 답입니다. 중복 값과 입력 개수의 최솟값·최댓값도 함께 확인합니다. 빈 배열·0·음수는 원문 범위 밖입니다.

공식 문서 참고: 관련 개념: MDN 나머지 연산으로 마지막 자릿수 꺼내기 · 관련 개념: MDN Math.floor로 양수의 정수 몫 구하기

읽기 전에 알아두면 좋아요

아래 개념이 익숙하면 본문을 바로 읽으세요. 낯선 개념만 링크에서 복습하면 됩니다.

개념과 예제는 실행하지 않아도 읽을 수 있습니다. 내 컴퓨터·터미널에서 직접 실행하는 과정은 선택 실습입니다.

과정 위치와 선택 복습 안내

과정 위치: 완전탐색과 격자 · 문제

과정 위치는 이 글이 속한 묶음입니다. 이 단계의 모든 개념을 먼저 읽을 필요는 없습니다. 위에 연결한 개념 중 낯선 내용만 복습하세요. 문제의 조건·상태·갱신 순서는 익숙한 언어로 설명하면 됩니다.

JavaScript로 문법·실행 복습하기 (선택)

개념 글의 코드는 JavaScript 예시입니다. 문제 화면에서는 JavaScript·Python·Java·C++·C# 중 익숙한 언어의 함수를 작성하세요. 본문의 Node.js 입출력 예시는 로컬 실행을 위한 별도 안내입니다.

128과 137의 자릿수를 나눠 보고 합이 같으면 더 큰 수를 고르는 그림

자릿수의 합이 같을 때 어떤 수를 남겨야 할까요? 각 수의 자릿수 합을 구한 뒤, 합이 같으면 원래 수가 더 큰 쪽을 선택하면 됩니다. 이 글에서는 배열을 한 번 순회하면서 두 비교 기준을 빠뜨리지 않는 함수를 구현합니다.

선수 지식은 배열, 반복문, 조건문, 함수의 반환값입니다. 나머지와 정수 몫으로 자릿수를 분리하는 과정은 아래에서 설명합니다. JavaScript를 기준으로 생각하되 실습에서는 Python·Java·C++·C#도 선택할 수 있습니다.

먼저 JavaScript 조건문과 반복문: 변수 값의 흐름부터 추적하기에서 조건·반복·값 갱신을 확인한 뒤, 이 글에서 각 수를 비교해 최선 후보를 선택합니다.

문제와 입출력

N개의 자연수 중 자릿수의 합이 가장 큰 원래 수를 구합니다. 합이 같은 수가 여러 개라면 그중 가장 큰 수를 반환합니다. 자릿수의 합 자체를 반환하는 문제가 아닙니다.

  • 입력 개수 N은 3 이상 100 이하입니다.
  • 각 수는 1 이상 10,000,000 이하입니다.
  • 표준 입력은 첫 줄에 N, 둘째 줄에 N개의 수가 주어지는 형태입니다.
  • 페이지 실습은 N과 배열을 함수에 전달하고 정수 하나를 반환합니다. 함수 안에서 표준 입출력을 처리하지 않습니다.
입력
7
128 460 603 40 521 137 123

출력
137

128과 137은 자릿수의 합이 모두 11입니다. 따라서 더 큰 원래 수인 137이 답입니다.

목차

직접 풀어보기

먼저 두 가지를 나눠 생각해 보세요. 한 수의 자릿수 합을 구하는 일과, 지금까지의 최선 후보를 고르는 일입니다. 후보를 저장할 때 원래 수와 자릿수 합 중 무엇을 각각 보관해야 할까요?

선택한 언어의 시작 코드와 호출 계약을 확인한 뒤 작성해 보세요. 아래 해답은 기본적으로 접혀 있습니다. 힌트와 정답 비교는 AI 설명이며 코드를 실제 실행하는 채점 결과가 아닙니다.

직접 풀어보기

먼저 선택한 언어의 입력·반환 계약에 맞춰 작성해 보세요. 힌트 받기와 정답과 비교하기는 코드를 실행하지 않는 AI 분석입니다. 해답·해설은 아래에서 필요할 때 펼칠 수 있습니다.

0 / 6,000바이트

호출: solution(n, arr) → number. n은 정수, arr는 number[]이다. 전제: 3 ≤ n ≤ 100, n == arr의 길이, 모든 원소는 1 이상 10,000,000 이하의 정수이다. 반환값은 자릿수의 합이 최대인 원래 수이며, 합이 같으면 원래 수가 더 큰 쪽이다. arr를 변경하지 않고, 표준 입력·출력은 처리하지 않는다. Tab은 다음 항목으로 이동합니다. 입력 영역 오른쪽 아래를 끌어 높이를 조절할 수 있습니다.

비밀키·개인정보는 입력하지 마세요. 코드는 이 페이지에만 유지됩니다.

해답·해설 보기
JavaScript 해답
function solution(n, arr) {
    let answer = 0;
    let bestSum = -1;

    for (let i = 0; i < n; i++) {
        const x = arr[i];
        let tmp = x;
        let sum = 0;

        while (tmp > 0) {
            sum += tmp % 10;
            tmp = Math.floor(tmp / 10);
        }

        if (sum > bestSum) {
            bestSum = sum;
            answer = x;
        } else if (sum === bestSum && x > answer) {
            answer = x;
        }
    }

    return answer;
}

호출: solution(n, arr) → number. n은 정수, arr는 number[]이다. 전제: 3 ≤ n ≤ 100, n == arr의 길이, 모든 원소는 1 이상 10,000,000 이하의 정수이다. 반환값은 자릿수의 합이 최대인 원래 수이며, 합이 같으면 원래 수가 더 큰 쪽이다. arr를 변경하지 않고, 표준 입력·출력은 처리하지 않는다.

풀이: 각 원래 수 x를 tmp에 복사한다. tmp가 0보다 큰 동안 tmp % 10을 sum에 더하고, tmp를 10으로 나눈 정수 몫으로 바꾼다. 이 순서는 일의 자리부터 한 자리씩 제거하며 모든 자릿수를 정확히 한 번씩 더한다. x는 끝까지 원래 값으로 유지한다.

선택 기준: bestSum은 지금까지 확인한 최대 자릿수 합, answer는 그 합을 가진 수 중 가장 큰 원래 수다. 처음에는 bestSum = -1, answer = 0으로 둔다. sum > bestSum이면 두 값을 갱신한다. sum == bestSum이면 x > answer일 때만 answer를 갱신한다. 따라서 반복이 끝나면 조건을 만족하는 원래 수가 answer에 남는다.

예제 추적: [128, 460, 603, 40, 521, 137, 123]의 자릿수 합은 차례로 [11, 10, 9, 4, 8, 11, 6]이다. 128과 137이 합 11로 같으므로 더 큰 원래 수 137을 반환한다. 반환값은 자릿수 합 11이 아니다.

경계 확인: 최소 개수 입력 [1, 2, 3]은 3이다. [235, 1234, 22]와 순서를 바꾼 [1234, 235, 22]는 모두 1234이다. 최댓값이 포함된 [10,000,000, 9,999,999, 1]은 자릿수 합이 63인 9,999,999를 고른다. [10,000,000, 1,000,000, 1]은 합이 모두 1이므로 10,000,000을 고른다. 100개 입력과 중복 원소도 같은 비교 규칙으로 처리한다. 빈 배열, 0, 음수는 원문 입력 범위 밖이다.

복잡도: N은 입력 개수, D는 가장 긴 수의 십진 자릿수이다. 시간은 O(ND), 입력 배열을 제외한 추가 공간은 O(1)이다. 이 문제에서는 D ≤ 8이므로 입력 상한을 고정하면 시간은 O(N)으로도 표현할 수 있다. 별도의 자릿수 배열이나 정렬은 필요하지 않다.

JavaScript 주의점: / 연산만 하면 소수가 남으므로 Math.floor(tmp / 10)으로 정수 몫을 구한다. 입력 상한 10,000,000은 Number의 안전한 정수 범위 안이다. 합 비교에는 ===를 사용한다. 원본 배열을 정렬하거나 원소를 직접 나누지 않는다.

접근 과정

1. 원래 수를 보존하며 한 자리씩 꺼냅니다

137을 10으로 나눈 나머지는 7입니다. 정수 몫 13으로 바꾸면 다음에는 3, 마지막에는 1을 얻습니다. 임시 값이 0이 될 때까지 반복하면 모든 자릿수를 한 번씩 더할 수 있습니다. 원래 수를 답으로 반환해야 하므로 나누는 대상은 별도 임시 변수로 둡니다.

JavaScript의 나눗셈은 소수가 남을 수 있어 Math.floor로 정수 몫을 구합니다. Python은 //를 사용하고, Java·C++·C#의 이 풀이에서는 양의 정수형 나눗셈을 사용합니다.

2. 합을 먼저, 동률이면 원래 수를 비교합니다

지금까지 가장 큰 합과 그 합을 가진 원래 수를 함께 저장합니다. 새로운 합이 더 크면 두 값을 모두 갱신합니다. 합이 같다면 원래 수가 더 큰 경우에만 답을 바꿉니다. 단순히 마지막 수를 남기면 입력 순서에 따라 답이 달라질 수 있습니다.

각 수를 처리한 직후에는 ‘현재 답이 지금까지 본 수 중 합이 최대이고, 그 안에서 원래 수가 가장 크다’는 성질이 유지됩니다. 처음 수부터 이 성질을 지키므로 배열을 끝까지 확인한 뒤의 답도 문제 조건을 만족합니다.

3. 예제에서 상태 변화를 따라갑니다

주어진 배열의 자릿수 합은 순서대로 11, 10, 9, 4, 8, 11, 6입니다. 첫 후보는 128이고, 이후 137을 만났을 때 합 11이 같지만 원래 수가 더 크므로 후보가 137로 바뀝니다. 마지막 123의 합은 6이므로 답을 유지합니다.

전체 풀이 코드와 언어별 해설

선택한 언어의 완전한 정답과 호출 계약은 이 해답 영역에서 함께 확인할 수 있습니다. 원본 TXT에는 정수 계산 풀이와 문자열로 바꿔 더하는 풀이가 있습니다. 여기서는 첫 번째 산술 접근을 유지하고 입력 개수에 맞춘 순회, 동률 조건, 원본 배열 보존을 명시했습니다.

경계값과 복잡도

별도로 만든 확인 입력 [235, 1234, 22]와 [1234, 235, 22]는 모두 1234를 골라야 합니다. 순서를 뒤집어도 동률 규칙은 바뀌지 않습니다. [10000000, 1000000, 1]처럼 합이 모두 1인 경우에는 10000000이 답입니다. 중복 값과 입력 개수의 최솟값·최댓값도 함께 확인합니다. 빈 배열·0·음수는 원문 범위 밖입니다.

가장 긴 수의 십진 자릿수를 D라고 하면 시간 복잡도는 O(ND), 입력 배열을 제외한 추가 공간은 O(1)입니다. 이 문제의 상한에서는 D가 최대 8이므로 O(N)으로 표현할 수도 있습니다. 배열을 정렬하거나 별도의 자릿수 배열을 만들 필요는 없습니다.

자가 확인

  • 자릿수 합이 아니라 원래 수를 반환하고 있나요?
  • 합이 같을 때 더 큰 원래 수를 고르며, 입력 순서를 바꿔도 결과가 같나요?
  • 임시 변수를 나누어 원본 배열과 원래 수를 보존하나요?
  • JavaScript에서는 정수 몫, Python에서는 정수 나눗셈을 사용했나요?

직접 실행하려면 선택한 언어의 정답을 해당 언어 파일에 저장하고 호출 계약대로 N과 배열을 전달하세요. JavaScript는 solution.js에 정답 함수와 console.log(solution(7, [128, 460, 603, 40, 521, 137, 123])); 호출을 넣고 node solution.js를 실행합니다. 기대 출력은 137입니다. 표준 입력 제출 환경에서는 입력을 읽는 부분과 이 함수를 연결해야 합니다.

출처와 검증 범위

문제 기준: 사용자가 제공한 알고리즘 자료의 섹션 4, 1번 ‘자릿수의 합’. 해당 PDF 첫 페이지의 조건·예제와 ‘1. 자리수의 합.txt’의 두 풀이를 2026년 10월 21일 대조했습니다. 문제 원문 전체를 재게시하지 않았으며 제공되지 않은 온라인 채점 주소는 추가하지 않았습니다.

실행 확인: JavaScript·Python·Java·C++는 원문 예제와 별도 경계·생성 입력 212개씩을 실행하고 배열 보존도 확인했습니다. C#은 이 검증 환경에 실행기가 없어 실제 실행하지 못했으며 문법·정수 범위·호출 계약·같은 비교 로직만 대조했습니다. AI 힌트와 비교 응답은 이 실행 검사를 대신하지 않습니다.

다음 학습

다음에는 완전탐색과 쌍 비교: 중복 없는 후보 열거와 순위 계산에서 후보 쌍을 중복 없이 열거하고 비교하는 방법으로 범위를 넓혀 보세요.

이 글이 도움이 되었나요?

조회 중

이어서 공부하기

체크포인트: 해설을 가리고 다시 풀고, 경계 입력을 하나 바꾸어 예상 결과와 실제 결과를 비교하세요. 같은 쌍을 두 번 세지 않는 이유와 모서리·대각선의 좌표를 설명하세요.

다음 추천 · 알고리즘 개념: 완전탐색과 쌍 비교: 중복 없는 후보 열거와 순위 계산

같은 주제에서 다음 개념과 예제로 이해를 넓힙니다.

권장 순서는 학습 가이드와 같습니다. 다른 순서는 접힌 참고 목록에서 확인할 수 있습니다. 읽음 표시는 숙달이나 채점 결과가 아닙니다.

원래 과정 목록 순서 (선택)

읽음 기록

읽음 — / 전체 57개 · 필수 57개

이 글을 쓴 해비

웹사이트를 제작·운영하고, 개인 서비스와 자동화·AI 도구를 만듭니다. 직접 만들며 배운 내용과 문제 해결 과정을 BlogFlow에 기록합니다.

새 글 받아보기

RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.

RSS 피드 구독하기

댓글 남기기