리주의 프로그래밍 공부

[1081] 합 본문

알고리즘 공부(백준)

[1081] 합

Leezu_ 2021. 3. 25. 23:00

우연히 문제를 알게 돼서 시도하다보니, 골드2 문제였다.. 난이도 보고 포기할까 싶었지만, 이왕 시작한거 끝을 보자는 마인드로 풀어냈다. (참고로 제출수가 적은 탓에 구글링해도 풀이가 다른 문제에 비해 많이 없다.)

 

 

접근방법

두 수를 받아서 한번에 풀라고 하지 않았다. 하나의 수에 대해 0~9까지 몇개히 문제를 알게 돼서 시도하다보니, 골드2 문제였다.. 난이도 보고 포기할까 싶었지만, 이왕 시작한거 끝을 보자는 마인드로 풀어냈다. (참고로 제출수가 적은 탓에 구글링해도 풀이가 다른 문제에 비해 많이 없다.)

 

 

 

 

 

접근방법

 

두 수를 받아서 한번에 풀라고 하지 않았다. 하나의 수에 대해 작거나 같은 모든 정수의 각 자리의 합을 구하는 함수를 작성한 뒤에, 그 함수를 두 번 호출해서 풀었다. (문제를 쪼개서 생각한 느낌..?) 덕분에 main에서 함수를 호출할 때, L값에는 -1을 해서 넣어줬다. 안그러면 L 자체에 해당하는 값을 잃게 된다.

import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		
		int L = sc.nextInt();
		int U = sc.nextInt();
		
        // L 자체의 값을 잃지 않기 위해서 L-1 을 넣어줬다.
		System.out.println(getSum(U) - getSum(L - 1));
	}
	
	public static long getSum(int a) {
   		// 값을 저장할 변수
		long sum = 0;
		// 0~9까지 개수를 카운팅할 배열
		long[] cnt = new long[10];
		
		// 0: 1의 자리, 1: 10의 자리, 2: 100의 자리 ...
		int[] digit = new int[10];
        
		// 각 자리수를 배열에 저장
        int temp = a;
		int idx = 0;
		while(temp != 0) {
			digit[idx++] = temp%10;
			temp /= 10;
		}
		
		// 임시 저장. 추후에 뒷 자리수를 구할 때, 사용
		int aside = a;
		// 일의 자리부터 시작
		int s = 0;
		while(a != 0) {
        	// 카운팅하려는 자리의 앞부분
			int n = a/10;
			
			// 일의 자리일 경우
			if(s == 0) {
				for(int i=1; i<= digit[s]; i++) {
                	// ex) 134의 경우, n=13
                    // 일의 자리에서 0~4까지는 14번씩 나온다
					cnt[i] += n + 1; 
				}
				for(int i=digit[s] + 1; i<10; i++) {
                	// ex) 134의 경우, n=13
                    // 일의 자리에서 5~9까지는 13번씩 나온다
					cnt[i] += n;
				}
			} else {
				for(int i=1; i<10; i++) {
					if(i < digit[s]) {
                    	// ex) 1234에서 백의 자리 계산시, n=1
                        // 백의 자리에서 0~1까지는
                        // 천의 자리가 0과1, 십의 자리 0~9, 일의 자리 0~9
                        // (1+1) * 10 * 10
						cnt[i] += (n + 1) * Math.pow(10, s);
					} else if(i == digit[s]) {
                    	// ex) 1234에서 백의 자리 계산시, n=1
                        // 백의 자리에서 2는
                        // 천의 자리가 0, 십의 자리 0~9, 일의 자리 0~9
                        // 1 * 10 * 10
                        // 추가적으로
                        // 천의자리가 1, 뒷 부분은 00~34
                        // 1 * 35
						cnt[i] += n * Math.pow(10, s) + (aside % Math.pow(10, s) + 1);
					} else {
                    	// ex) 1234에서 백의 자리 계산시, n=1
                        // 백의 자리에서 3~9는
                        // 천의 자리가 0, 십의 자리 0~9, 일의 자리 0~9
						cnt[i] += n * Math.pow(10, s);
					}
				}
			}
            // 자리수 증가
			s++;
			a /= 10;
		}
		
        // 모든 정수의 각 자리의 합 구하기
		for(int i=1; i<10; i++) {
			sum += cnt[i] * i;
		}
		
		return sum;
	}
}

'알고리즘 공부(백준)' 카테고리의 다른 글

[5639] 이진 검색 트리  (0) 2021.03.24
[1991] 트리 순회  (0) 2021.03.22
[11650] 좌표 정렬하기  (0) 2021.03.19
[15652] N과 M (4)  (0) 2021.03.19
[15650] N과 M (2)  (0) 2021.03.19