Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++로 숫자의 M개 연속 자릿수 최대 합과 곱 구하기

문제 개요

이 문제에서는 하나의 숫자를 나타내는 문자열이 주어집니다. 우리의 목표는 C++을 활용하여 숫자 안에서 M개의 연속된 자릿수를 선택했을 때 얻을 수 있는 최대 합(sum)과 최대 곱(product)을 구하는 프로그램을 작성하는 것입니다.

문제 설명

주어진 숫자에서 길이가 M인 모든 연속 부분 수열을 찾고, 각 부분 수열에 포함된 자릿수들의 합과 곱을 계산한 뒤, 그중 가장 큰 값을 반환합니다.

예시를 통해 문제를 자세히 이해해 보겠습니다.

입력

number = 2379641, M = 4

출력

maxSum = 26
maxProd = 1512

설명

크기가 4인 모든 연속 부분 수열은 2379, 3796, 7964, 9641입니다.
최대 합(maxSum) = 7 + 9 + 6 + 4 = 26
최대 곱(maxProd) = 7 × 9 × 6 × 4 = 1512

풀이 접근 방법

가장 직관적인 해결 방법은 숫자에서 만들 수 있는 길이 M의 모든 연속 부분 수열을 하나씩 살펴보는 것입니다. 각 부분 수열마다 자릿수의 합과 곱을 계산하고, 지금까지 구한 최댓값과 비교하여 더 큰 값으로 갱신합니다. 모든 경우를 확인한 뒤 최종적으로 남은 값이 바로 최대 합과 최대 곱입니다.

예제 코드

아래 프로그램은 위에서 설명한 풀이 과정을 그대로 구현한 예제입니다.

#include <iostream>
using namespace std;

// 두 값 중 더 큰 값을 반환하는 헬퍼 함수
int findMaxVal(int x, int y){
    return (x > y) ? x : y;
}

// M개의 연속 자릿수에 대한 최대 합과 곱을 계산하는 함수
void calcMaxProductAndSum(string number, int M){
    int N = number.length();
    int maxProd = -1, maxSum = -1;

    // 마지막 윈도우까지 포함하기 위해 i <= N - M 조건 사용
    for (int i = 0; i <= N - M; i++){
        int product = 1, sum = 0;
        for (int j = i; j < M + i; j++){
            product *= (number[j] - '0');
            sum += (number[j] - '0');
        }
        maxProd = findMaxVal(maxProd, product);
        maxSum = findMaxVal(maxSum, sum);
    }

    cout << "숫자 " << number << "에서 연속된 " << M << "개 자릿수의 최대 곱: " << maxProd << endl;
    cout << "숫자 " << number << "에서 연속된 " << M << "개 자릿수의 최대 합: " << maxSum;
}

int main() {
    string str = "2379641";
    int m = 4;
    calcMaxProductAndSum(str, m);
    return 0;
}

출력 결과

숫자 2379641에서 연속된 4개 자릿수의 최대 곱: 1512
숫자 2379641에서 연속된 4개 자릿수의 최대 합: 26

시간 복잡도 분석

위 풀이는 시작 위치마다 M개의 자릿수를 다시 계산하므로 시간 복잡도는 O(N×M)입니다. 여기서 N은 숫자의 전체 길이입니다. 슬라이딩 윈도우 기법을 적용하면 윈도우가 한 칸 이동할 때 빠져나가는 자릿수와 새로 들어오는 자릿수만 반영하면 되므로, 시간 복잡도를 O(N)까지 줄일 수 있습니다.

마무리

이처럼 문자열로 표현된 숫자에서 각 문자에 '0'을 빼주면 손쉽게 정수형 자릿값으로 변환할 수 있으며, 이를 활용해 연속 구간의 합과 곱을 효율적으로 계산할 수 있습니다. 입력 크기가 커질 가능성이 있다면 슬라이딩 윈도우 최적화를 함께 고려하는 것이 좋습니다.