반응형
문제
지민이는 전체 페이지의 수가 N인 책이 하나 있다. 첫 페이지는 1 페이지이고, 마지막 페이지는 N 페이지이다. 각 숫자가 전체 페이지 번호에서 모두 몇 번 나오는지 구해보자.
입력
첫째 줄에 N이 주어진다. N은 1,000,000,000보다 작거나 같은 자연수이다.
출력
첫째 줄에 0이 총 몇 번 나오는지, 1이 총 몇 번 나오는지, ..., 9가 총 몇 번 나오는지를 공백으로 구분해 출력한다.
예제 입력 1
11
예제 출력 1
1 4 1 1 1 1 1 1 1 1
예제 입력 2
7
예제 출력 2
0 1 1 1 1 1 1 1 0 0
예제 입력 3
19
예제 출력 3
1 12 2 2 2 2 2 2 2 2
예제 입력 4
999
예제 출력 4
189 300 300 300 300 300 300 300 300 300
예제 입력 5
543212345
예제 출력 5
429904664 541008121 540917467 540117067 533117017 473117011 429904664 429904664 429904664 429904664
소스코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
private static BufferedReader br;
private static StringTokenizer st;
private static int N, cnt[];
public static void main(String[] args) throws NumberFormatException, IOException {
br=new BufferedReader(new InputStreamReader(System.in));
N=Integer.parseInt(br.readLine());
cnt=new int[10];
long start=1;
long end=N;
long size=1;
outer : while(start<=end) {
while(start%10!=0) { // 앞 남는 부분
getRemain(start, size);
start++;
if(start>end) break outer;
}
while(end%10!=9) { // 뒤 남는 부분
getRemain(end, size);
end--;
if(start>end) break outer;
}
end/=10;
start/=10;
for(int i=0;i<10;i++) { // 0~9 사이
cnt[i]+=(end-start+1)*size;
}
size*=10;
}
for(int i=0;i<10;i++) System.out.print(cnt[i]+" ");
}
private static void getRemain(long x, long size) { // 남는 부분의 자릿수에 해당하는 숫자 개수 계산
String s=String.valueOf(x);
for(int i=0;i<s.length();i++) {
cnt[s.charAt(i)-'0']+=size;
}
}
}
단순히 반복문만 이용하게 되면 시간 초과가 발생하므로 수학적으로 접근해야 하는 문제였습니다.
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | ... | ||||||||
30 | ... | ||||||||
40 | 41 | 42 | 43 |
N이 43인 경우를 살펴보면, 일의 자리의 수가 0~9인 구간은 10~39까지 존재합니다. 이것을 기준으로 앞 남는 부분과 뒤 남는 부분을 따로 계산하여 해당 구간의 계산값과 더해주면 결과를 얻을 수 있습니다.
1. 앞 남는 부분 : 나머지가 0이 나오기 전까지 현재 숫자를 1부터 1씩 증가시키며 getRemain을 통해 각 자리의 숫자의 개수를 더해줍니다.
2. 뒤 남는 부분 : 나머지가 9가 나오기 전까지 현재 숫자를 N부터 1씩 감소시키며 getRemain을 통해 각 자리의 숫자의 개수를 더해줍니다.
3. 0~9 구간 : 해당 숫자값을 10으로 나누고, 나머지를 size(10의 배수 단위)로 개수 저장해줍니다. -> 10으로 나눈 값이 0보다 큰 경우 해당 숫자값을 10으로 나누고, size 값을 10배하는 과정을 반복합니다.
4. 최종적으로 0~9에 저장된 숫자의 개수를 출력합니다.
반응형
'코딩테스트 > 기타' 카테고리의 다른 글
[Java] 백준 2747번 : 피보나치 수 (0) | 2022.05.16 |
---|---|
[Java] 백준 15666번 : N과 M (12) (0) | 2022.04.16 |
[Java] 백준 15657번 : N과 M (8) (0) | 2022.04.09 |
[Java] 백준 15961번 : 회전 초밥 (0) | 2022.04.05 |
[Java] 백준 13458번 : 시험 감독 (0) | 2022.04.03 |