-
백준 1019번 책 페이지 :: 마이구미알고리즘 풀이/수학 2017. 7. 8. 18:56반응형
이번 글은 백준 알고리즘 1019번 "책 페이지" 를 다뤄본다.
모 회사에서도 코딩 테스트로 출제되었다고 한다.
문제 풀이는 규칙을 찾은 후 구현해야하는 수학적인 사고가 필요하다.
지민이는 N쪽인 책이 한권 있다. 첫 페이지는 1쪽이고, 마지막 페이지는 N쪽이다. 각 숫자가 모두 몇 번이 나오는지 출력하는 프로그램을 작성하시오.
문제는 보다시피 정말 간단하다.
본인은 백준 사이트의 CEO 백준님의 자료를 통해 문제를 해결했다. 참고 자료
자료를 보더라도, 이해하기가 쉽지 않았다.
참고 자료를 보면 1 ~ N이 아닌 A ~ B를 예로 들었다.
핵심은 A는 일의 자리가 0이 되어야하고, B는 일의 자리가 9가 되어야하고, 각 자릿수를 나누어서 생각한다.
(일의 자리에 대한 횟수, 십의 자리에 대한 횟수, 백의 자리에 대한 횟수.....)
특정 숫자의 각 자릿수를 뽑을 때는, % 10, / 10 를 통해 할 수 있다.
1234
1234 % 10 = 4
1234 / 10 = 123 => 123 % 10 = 3
123 / 10 = 12 => 12 % 10 = 2
12 / 10 = 1 => 1 % 10 = 1
0, 9를 만들어야하는 이유는 아래와 같은 규칙 때문이다.
A = 10, B = 39인 경우를 보자.
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
- 30, 31, 32, 33, 34, 35, 36, 37, 38, 39
보다시피 0 ~ 9의 횟수의 규칙을 볼 수 있다.
각 수의 횟수는 3 - 1 + 1 로 구할 수 있다. (39 / 10 = 3, 10 /10 = 1 || B / 10 - A / 10 + 1)
십의 자리, 백의 자리를 구할 때도 동일하다.
A = 1345 B = 8742 ==> A = 1350 B = 8739 일의 자리
-> 0~9의 각 횟수 (873 - 135 + 1) * 1
A = 135 B = 873 ==> A = 139 B = 869 십의 자리
-> 0~9의 각 횟수 (86 - 13 + 1) * 10
A = 13 B = 36 ==> A = 19 B = 29 백의 자리
-> 0~9의 각 횟수 (2 - 1 + 1) * 100
A = 1 B = 2 ==> 천의 자리
구현 방식은 위처럼 순서대로 하면 된다.
- 페이지의 번호의 일의 자리를 9로 만든다.
- 시작 번호의 일의 자리를 0으로 만든다.
- 만들어진 두 수를 규칙을 이용해 0~9의 횟수를 추가한다. (B / 10 - A / 10 + 1)
0과 9를 만드는 과정에서의 횟수는 단순히 자릿수를 더하면 된다.
예를 들어, 십의 자리를 구하기 위해 135 -> 136을 바꾸는 과정을 보자.
135은 사실상 1350이기 때문에, 1350 -> 1360으로 바꾸는 과정이 된다.
결과적으로 1이 10번, 3이 10번, 5가 10번 나오게 된다.
이 부분은 코드 중 아래 코드가 된다.
public static void cal(int x, int[] ans, int point) { while (x > 0) { ans[x % 10] += point; x /= 10; } }
12345678910111213141516171819202122232425262728293031323334353637383940414243444546private void solve() {// http://mygumi.tistory.com/180int page = sc.nextInt();int[] ans = new int[10];int point = 1;int start = 1;while (start <= page) {// 끝자리 9로 만들기while (page % 10 != 9 && start <= page) {cal(page, ans, point);page--;}if (page < start) {break;}// 끝자리 0으로 만들기while (start % 10 != 0 && start <= page) {cal(start, ans, point);start++;}start /= 10;page /= 10;for (int i = 0; i < 10; i++) {ans[i] += (page - start + 1) * point;}point *= 10;}for (int i = 0; i < 10; i++) {System.out.print(ans[i] + " ");}}public static void cal(int x, int[] ans, int point) {while (x > 0) {ans[x % 10] += point;x /= 10;}}cs 반응형'알고리즘 풀이 > 수학' 카테고리의 다른 글
백준 4158번 CD :: 마이구미 (0) 2017.09.02 백준 14653번 너의 이름은 :: 마이구미 (0) 2017.08.22 백준 14583번 이음줄 :: 마이구미 (0) 2017.05.28 백준 2942번 퍼거슨과 사과 [최대공약수] :: 마이구미 (0) 2017.05.23 백준 13900번 순서쌍의 곱의 합 [부분합] :: 마이구미 (0) 2017.05.21