본문 바로가기

별걸다하는 IT/알고리즘 문제풀이

[백준 알고리즘 2577번, 2006한국정보올림피아드 초등부] 숫자의 개수 알고리즘 문제 풀기 & 해설, 타입 범위 확인 메서드

정답률: 65.1%

난이도: 하

백준 알고리즘 분류: 1차원 배열 사용하기

출처: 한국정보올림피아드 2006년 지역본선

[2577번 문제] 숫자의 개수

문제

세 개의 자연수 A, B, C가 주어질 때 A×B×C를 계산한 결과에 0부터 9까지 각각의 숫자가 몇 번씩 쓰였는지를 구하는 프로그램을 작성하시오.

예를 들어 A = 150, B = 266, C = 427 이라면

A × B × C = 150 × 266 × 427 = 17037300 이 되고,

계산한 결과 17037300 에는 0이 3번, 1이 1번, 3이 2번, 7이 2번 쓰였다.

 

제한

시간 제한: 1초

메모리 제한: 128MB

 

입출력

입력: 첫째 줄에 A, 둘째 줄에 B, 셋째 줄에 C가 주어진다. A, B, C는 모두 100보다 같거나 크고, 1,000보다 작은 자연수이다.

출력: 첫째 줄에는 A×B×C의 결과에 0 이 몇 번 쓰였는지 출력한다. 마찬가지로 둘째 줄부터 열 번째 줄까지 A×B×C의 결과에 1부터 9까지의 숫자가 각각 몇 번 쓰였는지 차례로 한 줄에 하나씩 출력한다.

예제 입력

예제 출력

150

266

427

3

1

0

2

0

0

0

2

0

0

 

같이 풀이보기 뚜뚠!

밑에 답안! 해설

 

 

 

ANSWER

아무래도 곱하기가 있으면 제일 먼저 드는 생각을 'int로 했다가는 수를 다 못담을 수도 있겠다'가 떠오르네요. 한 번 int에 다 담기는지 체크하고 진행할 필요성이 있겠어요 ㅎㅎ 그리고 각 자리에 있는 수를 뽑아내는 작업이 필요하겠죠? 배열로 담아서 한 번에 처리하든 즉각 처리하든 처리 방식에 차이는 있을 수 있겠지만!

[C++ int 범위 체크]

#include <iostream>
#include <limits.h>
using namespace std;

int main() {
	int a, b, c; 
	int total;
	cin >> a >> b >> c;
	total = a * b * c;
	cout << "total:\t"<< total << "\n";
	cout << "max:\t"<< INT_MAX << "\n";
	return 0;
}

여기에 입력 최대 값인 999를 넣어보면!

max가 훨씬 크네요! int를 사용해도 문제가 없겠어요 ㅎㅎ

 

전체코드 C++

[2577번 C++]

#include <iostream>
#include <vector>
using namespace std;

int main() {
	int a, b, c, total, digit; 
	int digits[10]; fill_n(digits, 10, 0);
	cin >> a >> b >> c;
	total = a * b* c;
	vector<int> num;

	while (total != 0) {
		digit = total % 10;
		num.push_back(digit);
		total /= 10;
	}

	for (int i = 0; i < num.size(); i++) {
		digits[num[i]]++;
	}
	for (int count : digits) {
		cout << count << "\n";
	}
	return 0;
}

digits는 9 인덱스를 가지는데, 각 배열의 공간은, [0의 개수, 1의 개수, 2의 개수, ... , 9의 개수]를 의미해요

각 자리수를 하나하나 판별하면서 나아가는 방법입니다. 만약 그 자리수가 3이면 3의 개수 값을 +1 해주는거죠! 오늘 문제는 난이도가 굉장히 쉬운 편이네요 ㅎㅎ

 

숫자를 배열에 옮기는 것은 이전 문제에서 많이 했었죠!

do {
	digit = total % 10;
	num.push_back(digit);
} while ((total /= 10)!=0);

똑같은 로직이지만 do while을 써서..?ㅎㅎㅎ

만약 이렇게 수를 배열로 변환하는 과정이 있는 비슷한 문제를 추가로 풀어보고 싶다! 아래 포스팅도 풀어봅시다.

 

[백준 Baekjoon 알고리즘] 4673번 셀프 넘버 문제 및 풀이, 오답 풀이

[백준 Baekjoon Algorithm] [4673] 셀프 넘버 self number? 문제 셀프 넘버는 1949년 인도 수학자 D.R Kaprekar가 이름 붙였다. 양의 정수 n에 대해서 d(n)을 n과 n의 각 자리수를 더하는 함수라고 정의하자. 예를..

jhnyang.tistory.com

 

다음은 자바 코드를 살펴봅시다.

[JAVA- int 범위 체크]

자바에서도 똑같이 범위 체크 코드로 시작을 해볼게요

package justTest;
import java.util.Scanner;
public class Main{	
	public static void main(String[] args) {
    	Scanner sc = new Scanner(System.in);
    	int a = sc.nextInt();
    	int b = sc.nextInt();
    	int c = sc.nextInt();
    	int total = a*b*c;
    	
    	System.out.println(total);
    	System.out.println(Integer.MAX_VALUE);
    } 
}

자바는 Integer클래스가 내부적으로 값을 포함하고 있어서 Integer.MAX_VALUE로 확인하실 수 있습니다.

결과창↓

 

전체코드 JAVA

위에서 숫자를 배열로 변환하는 방법을 사용했으니까 이번에는 숫자를 문자열로 변환해서 풀어볼게요! 

import java.util.Scanner;
public class Main{	
	public static void main(String[] args) {
    	Scanner sc = new Scanner(System.in);
    	int a = sc.nextInt();
    	int b = sc.nextInt();
    	int c = sc.nextInt();
    	int []digits = new int[10];
    	String num = String.valueOf(a*b*c);
    	for(int i=0; i<num.length(); i++) {
    		digits[Integer.parseInt(num.charAt(i)+"")]++;
    	}
    	for(int d: digits) {
    		System.out.println(d);
    	}
    } 
}

메모리: 14260

시간: 104ms

코드 길이: 471B

오늘은 여기까지입니다~~ㅎㅎㅎ 다들 너무 수고했어요 !

 

  • 이연주 2020.03.24 12:50

    fill_n 이부분을 꼭 추가해야 하는 이유가 뭘까요?
    int digits[10] 에 따로 value지정 안하면 자동으로 0 으로 채워지는 거 아닌가요?

    • IT 양햄찌(jhnyang) 2020.03.24 14:28 신고

      언어적 차이가 있습니다. 버전 차이도 있고요. 자바 같은 경우는 자동적으로 0으로 채워주지만 C언어 같은 경우 쓰레기 값이 들어가 있을 수 있기 때문입니다. 값이 대입되어 덮어씌어진다면 문제가 발생하지 않겠지만, 그렇지 않을 경우를 위해 초기화시켜주었습니다.

    • 이연주 2020.03.25 06:13

      오..일년전 포스트라 답변을 주실까하고 있었는데 설명 감사합니다~ 코드 너무 잘보고 있어요!!
      다양한 언어들로 한 문제를 여러번 풀어주시니 더욱 도움이 되는거 같네용ㅎㅎ
      고맙습니다:)
      요즘 같이 힘든날 화이팅하세요!