[백준] 1019 책 페이지
완탐… 은 애저녁에 포기했고 규칙을 생각해보기로 했다!
각 자릿수별로 각 숫자가 몇개나 나올 수 있을지를 생각해보면 된다. 1의 자리부터 시작해서 제일 큰 자릿수까지 진행해가며 세어주게끔 작성했다. 자세한 내용은 주석을 통해 확인하자~!
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Main{
static int ip(String s){ return Integer.parseInt(s); };
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = ip(br.readLine());
long[] nums = new long[10]; // 각 숫자의 갯수를 저장할 배열
String s = String.valueOf(n); // 받아온 숫자를 문자열로 전환해주었다 (자릿수별로 따질거라서 필요함)
int len = s.length(); // 숫자의 길이를 알면 최대 몇자린지 금방 알 수 있다
long ten = 10; // 이건 앞으로 10, 100, 1000, ... 이 되어줄 값이다
for(int i = len-1 ; i >= 0 ; i--) { // i는 자릿수를 뜻하며 len-1자리는 일의 자리가 된다.
int last = s.charAt(i) - '0'; // 해당 자릿수의 숫자를 알아낸다
for(int j = 0 ; j < last ; j++) { // 0 ~ last 직전까지의 숫자의 갯수를 세어보자
if( i == 0 && j == 0 ) continue; // 예외처리 : 제일 큰 자릿수를 따질땐 0의 자릿수를 세는것은 무의미하다
// 기본적으로 현재 자릿수보다 더 앞자리가 굴러가는 만큼 지금 자릿수의 숫자가 반복되어 나타나게 된다.
// 예를 들어 8765가 있을 때 십의 자릿수를 따지는 중이라면
// 6(last)보다 작은, 예를들어 5가 몇번이나 반복될 지 생각해보자
// 8750~ 0050 까지 온전히 반복되며, 일의 자릿수는 0~9까지 모두 가능하므로 (87 + 1) * 10 이 된다. // 단 0일때는 좀 주의를 해야한다. 마지막 00'0'0 인 부분은 세면 안된다. 중복되어버림...
if( j == 0 ) {
nums[j] += (n/ten) * (ten/10);
}else {
nums[j] += (n/ten + 1) * (ten/10);
}
}
// last 자릿수의 경우 주의할 점은, 앞자리숫자만큼 온전히 반복될 수 없고 약간 잘려야 한다는것이다.
// 예를 들면 8765가 있을 때, 십의 자릿수를 따지는 중이라면
// 6은 8660 ~ 0060 까지 온전히 반복되며, 일의 자릿수는 0~9까지 모두 가능하므로 87 * 10 이 된다.
// 추가적으로 8760~ 8765 까지 6번 더 가능하기 때문에 (n%(ten/10)) + 1 를 넣어준 것이다.
if(last == 0 && i != 0) {
nums[last] += (n/ten -1) * (ten/10) + (n%(ten/10)) + 1;
}else {
nums[last] += (n/ten) * (ten/10) + (n%(ten/10)) + 1;
}
// 마지막으로 8765 에서 십의자리에 7 이상의 값이 오는 경우는 (7이라고 치면)
// 8670 ~ 0070 까지 온전히 반복되며, 일의 자릿수는 0~9까지 모두 가능하다. 따라서 87 * 10
for(int j = last+1 ; j <= 9 ; j++) {
nums[j] += (n/ten)*(ten/10);
}
// 자릿수를 올려준다
ten *= 10;
}
//출력
for(int i = 0 ; i < 10 ; i++) {
System.out.print(nums[i] + " ");
}
}
}
Comments