[λ°±μ€€] 1790 - 수 이어 μ“°κΈ°2

문제

문제 μ„€λͺ…

Baekjoon Online Judge - 1790번 수 이어 μ“°κΈ°2

1λΆ€ν„° NκΉŒμ§€μ˜ 수λ₯Ό μ΄μ–΄μ„œ μ“°λ©΄ λ‹€μŒκ³Ό 같이 μƒˆλ‘œμš΄ ν•˜λ‚˜μ˜ 수λ₯Ό 얻을 수 μžˆλ‹€.

1234567891011121314151617181920212223…

μ΄λ ‡κ²Œ λ§Œλ“€μ–΄μ§„ μƒˆλ‘œμš΄ μˆ˜μ—μ„œ, μ•žμ—μ„œ k번째 자리 μˆ«μžκ°€ μ–΄λ–€ μˆ«μžμΈμ§€ κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

μž…λ ₯

첫째 쀄에 N(1 ≀ N ≀ 100,000,000)κ³Ό, k(1 ≀ k ≀ 1,000,000,000)κ°€ μ£Όμ–΄μ§„λ‹€. Nκ³Ό k μ‚¬μ΄μ—λŠ” 곡백이 ν•˜λ‚˜ 이상 μžˆλ‹€.

좜λ ₯

첫째 쀄에 μ•žμ—μ„œ k번째 자리 숫자λ₯Ό 좜λ ₯ν•œλ‹€. 수의 길이가 k보닀 μž‘μ•„μ„œ k번째 자리 μˆ«μžκ°€ μ—†λŠ” κ²½μš°λŠ” -1을 좜λ ₯ν•œλ‹€.

μž…μΆœλ ₯ 예

μž…λ ₯ 좜λ ₯
20 23 6

풀이

ν•΄μ„€

  1. 1λΆ€ν„° NκΉŒμ§€ 수λ₯Ό 이어적어 λ§Œλ“  수의 길이(숫자 개수)λ₯Ό κ΅¬ν•œ λ’€ k와 λΉ„κ΅ν•˜μ—¬ μ˜ˆμ™Έμ²˜λ¦¬
  2. μ•žμ—μ„œλΆ€ν„° k번째 자리 숫자의 μ‹€μ œ 수 κ΅¬ν•˜κΈ°

    1. μ•žμ—μ„œλΆ€ν„° k번째 자리 μˆ«μžκ°€ μ†ν•œ 수 κ΅¬ν•˜κΈ°
    2. 2-iμ—μ„œ κ΅¬ν•œ 수의 λͺ‡λ²ˆμ§Έ 자리 μˆ«μžμΈμ§€ κ΅¬ν•˜κΈ°(μ΅œμ’… 좜λ ₯ κ°’)

1-1. 자리수 별 숫자 개수 κ΅¬ν•˜κΈ°

Accumulation Index Sum

문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œλŠ” 1λΆ€ν„° λ‚˜μ—΄λœ μˆ˜λ“€μ˜ λͺ¨μž„μ—μ„œ νŠΉμ • μˆ«μžκ°€ λͺ‡ 번째 μžλ¦¬μ— μœ„μΉ˜ν•œ μˆ«μžμΈμ§€ κ·Έ 관계λ₯Ό μ•Œμ•„μ•Ό ν•œλ‹€.

λ”°λΌμ„œ 숫자의 개수λ₯Ό ꡬ해야 ν•˜λŠ”λ°, 각 μˆ˜λŠ” μžμ‹ μ˜ 자리수만큼의 숫자둜 κ΅¬μ„±λ˜μ–΄ μžˆμœΌλ―€λ‘œ 각 μžλ¦¬μˆ˜μ— μ‘΄μž¬ν•˜λŠ” 수의 κ°œμˆ˜μ™€ 자리수λ₯Ό κ³±ν•˜λ©΄ ν•΄λ‹Ή μžλ¦¬μˆ˜μ— μ†ν•œ 수의 전체 길이λ₯Ό ꡬ할 수 μžˆλ‹€.

  • ν•œ 자리 수(1~9)λŠ” 9κ°œκ°€ μ‘΄μž¬ν•˜κ³  ν•œ 자리 수의 λ§ˆμ§€λ§‰ 수인 9의 μΈλ±μŠ€λŠ” 9
  • 두 자리 수(10~99)λŠ” 180κ°œκ°€ μ‘΄μž¬ν•˜κ³  두 자리 수의 λ§ˆμ§€λ§‰ 수인 99의 μΈλ±μŠ€λŠ” 189
  • μ„Έ 자리 수(100~999)λŠ” 2700κ°œκ°€ μ‘΄μž¬ν•˜κ³  μ„Έ 자리 수의 λ§ˆμ§€λ§‰ 수인 999의 μΈλ±μŠ€λŠ” 2889
  • λ„€ 자리 수(1000~9999)λŠ” 36000κ°œκ°€ μ‘΄μž¬ν•˜κ³  λ„€ 자리 수의 λ§ˆμ§€λ§‰ 수인 9999의 μΈλ±μŠ€λŠ” 38889

1-2. k의 μ˜ˆμ™Έμ²˜λ¦¬

μœ„μ˜ 방법을 μ΄μš©ν•˜μ—¬ 1λΆ€ν„° NκΉŒμ§€ 수λ₯Ό μ΄μ–΄μ μ—ˆμ„ λ•Œ λ§Œλ“€μ–΄μ§€λŠ” 수의 길이λ₯Ό ꡬ할 수 μžˆλ‹€.

  • N의 μžλ¦¬μˆ˜λ³΄λ‹€ ν•œ 자리 μž‘μ€ 자리수의 λ§ˆμ§€λ§‰ μˆ˜κΉŒμ§€μ˜ 인덱슀λ₯Ό κ³„μ‚°ν•œλ‹€.

    -> 20은 두 자리수 μ΄λ―€λ‘œ ν•œ 자리수의 λ§ˆμ§€λ§‰ 수인 9κΉŒμ§€ 인덱슀λ₯Ό κ΅¬ν•˜λ©΄ 9

  • μ΄ν›„μ—λŠ” ν˜„μž¬ 자리수의 μˆ˜λ“€ 쀑 N이 λͺ‡λ²ˆμ§Έ μˆ˜μΈμ§€ κ΅¬ν•˜κ³  λ‹€μ‹œ 자리수λ₯Ό κ³±ν•œλ‹€.

    -> 두 자리 μˆ˜λ“€ 쀑 20κΉŒμ§€λŠ” 11개의 μˆ˜κ°€ μ‘΄μž¬ν•˜κ³ , 각 μˆ˜λ“€μ€ λͺ¨λ‘ 2자리 μˆ˜μ΄λ―€λ‘œ 11 * 2 = 22

  • μœ„μ—μ„œ κ΅¬ν•œ 숫자 개수λ₯Ό λ”ν•˜λ©΄ 총 숫자 개수λ₯Ό ꡬ할 수 μžˆλ‹€!

    -> 9 + 22 = 31

λ”°λΌμ„œ 수의 κΈΈμ΄λŠ” μ΅œλŒ€ 31을 λ„˜μ§€ λͺ»ν•˜λ―€λ‘œ μž…λ ₯된 kκ°€ 31 이상일 경우 -1을 λ°˜ν™˜ν•œλ‹€.

  1. k번째 자리 숫자 κ΅¬ν•˜κΈ°

Calculate Index Principle-picture

Calculate Index Principle-text


2-1. k번째 μˆ«μžκ°€ μ†ν•œ 수

μ΅œμ’… λͺ©ν‘œμΈ k번째 숫자λ₯Ό κ΅¬ν•˜κΈ°μ— μ•žμ„œ k번째 μˆ«μžκ°€ μ†ν•œ 수λ₯Ό κ΅¬ν•˜λŠ” 것이 더 쉽닀.

kλ²ˆμ§Έμ—μ„œ kλŠ” μˆ˜κ°€ μ•„λ‹ˆλΌ μœ„μΉ˜ 정보인 인덱슀λ₯Ό μ˜λ―Έν•˜λ―€λ‘œ 1)μ—μ„œμ™€ μœ μ‚¬ν•˜κ²Œ 자리수λ₯Ό μ΄μš©ν•˜λ©΄ λœλ‹€.

단, 1)μ—μ„œλŠ” μ‹€μ œ μˆ˜κ°€ λͺ‡ λ²ˆμ§ΈμΈμ§€ μœ„μΉ˜(인덱슀)λ₯Ό κ΅¬ν–ˆλ‹€λ©΄, μ΄λ²ˆμ—λŠ” λ°˜λŒ€λ‘œ μœ„μΉ˜(인덱슀)λ₯Ό 톡해 μ‹€μ œ 수λ₯Ό ꡬ해야 ν•˜λ―€λ‘œ, 자리수 별 λ§ˆμ§€λ§‰ 수의 μΈλ±μŠ€κ°€ μ•„λ‹Œ 수 자체λ₯Ό μ΄μš©ν•˜κ³  자리수 λ‚˜λˆ„κΈ° 연산을 ν•΄μ•Όν•œλ‹€.

  • k의 μžλ¦¬μˆ˜λ³΄λ‹€ ν•œ 자리 μž‘μ€ 자리수의 λ§ˆμ§€λ§‰ 수λ₯Ό κ΅¬ν•œλ‹€.

    -> 23은 두 자리수 μ΄λ―€λ‘œ ν•œ 자리수의 λ§ˆμ§€λ§‰ 수인 9

  • μ΄ν›„μ—λŠ” ν˜„μž¬ 자리수의 μˆ«μžλ“€ 쀑 kκ°€ λͺ‡λ²ˆμ§Έ μˆ«μžμΈμ§€ κ΅¬ν•˜κ³  자리수둜 λ‚˜λˆˆλ‹€.

    -> kλŠ” 두 자리 수의 μˆ«μžλ“€ 쀑 (23 - 9)번째이고 각 μˆ˜λ“€μ€ λͺ¨λ‘ 2자리 수
    14 / 2 = 7(λ‘μžλ¦¬ μˆ˜λ“€ 쀑 7번째 수)

  • μœ„μ—μ„œ κ΅¬ν•œ 수λ₯Ό λ”ν•˜λ©΄ kκ°€ μ†ν•œ 수인 16을 λ„μΆœν•  수 μžˆλ‹€.

2-2. k번째 μˆ«μžκ°€ μ†ν•œ μˆ˜μ—μ„œ μ΅œμ’… 숫자 κ΅¬ν•˜κΈ°

이제 거의 λ‹€μ™”λ‹€!!πŸ˜‚

k번째 μˆ«μžκ°€ μ†ν•œ 수인 16μ—μ„œμ˜ μœ„μΉ˜λŠ” 2-1)μ—μ„œ ν•œ λ‚˜λˆ„κΈ° μ—°μ‚°μ˜ λ‚˜λ¨Έμ§€λ₯Ό 보면 λœλ‹€.

  • λ‚˜λ¨Έμ§€κ°€ 0의 경우 : k번째 μˆ«μžκ°€ μ†ν•œ 수의 자리수번째 μˆ˜λΌλŠ” 의미둜 수의 κ°€μž₯ λ§ˆμ§€λ§‰ 숫자λ₯Ό κ°€λ¦¬ν‚€λŠ” 것을 의미
  • λ‚˜λ¨Έμ§€κ°€ 1 ~ (k번째 μˆ«μžκ°€ μ†ν•œ 수의 자리수-1) μ‚¬μ΄μ˜ 값일 경우 : k번째 μˆ«μžκ°€ μ†ν•œ 수의 첫번째 μˆ«μžλΆ€ν„° 1둜 μΈλ±μ‹±ν•˜μ—¬ μ ‘κ·Όν•΄μ•Ό 함

μ•„μš° κΈ€λ‘œ μ“°λŠ”κ²Œ λ”νž˜λ“€λ‹€.

μ½”λ“œ

Java
import java.util.Scanner;

public class Baekjoon1790 {
	static Integer n, k;
	static String N;
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		k = sc.nextInt();
		N = Integer.toString(n);
		findNumberLocation();
	}
	
	static void findNumberLocation() {
		int nPlace = N.length();   // n의 자리수
		int nDigits = 0;           // nκΉŒμ§€ 이어뢙인 수의 전체 길이(숫자 개수, 인덱슀); k μ˜ˆμ™Έμ²˜λ¦¬λ₯Ό μœ„ν•΄ 계산
        int underKPlace = 0;       // k번째 수의 자릿수 - 1
		int underKDigits = 0;      // (k번째 수의 자릿수 - 1)κΉŒμ§€ 숫자 개수

		// (N의 자리수 - 1)κΉŒμ§€ 숫자 개수 κ΅¬ν•˜κΈ°(9개 + 180개 + 2700개 ...)
		for (int place=1; place<nPlace; place++) {
			nDigits += (9 * (int) Math.pow(10, place-1) * place);

            // k번째 수λ₯Ό μœ„ν•΄ (k번째 수의 자리수 - 1)κΉŒμ§€μ˜ 숫자 개수, 자리수 κΈ°μ–΅
			if (k >= nDigits) {
				underKDigits = nDigits;
				underKPlace = place;
			}
		}

		// N의 μžλ¦¬μˆ˜μ— ν•΄λ‹Ήν•˜λŠ” μˆ˜λ“€μ˜ 숫자 개수λ₯Ό ꡬ해 μ΅œμ’… nDigits 계산
		nDigits += (n - (int)(Math.pow(10, nPlace-1) - 1)) * nPlace;

		// kκ°€ 1λΆ€ν„° nκΉŒμ§€ 이어뢙인 수의 전체 길이λ₯Ό μ΄ˆκ³Όν•˜λŠ”μ§€ 체크
		if (k > nDigits) {
			System.out.println(-1);
		} else {
			// k번째 수의 μžλ¦¬μˆ˜μ— ν•΄λ‹Ήν•˜λŠ” μˆ˜λ“€μ˜ 개수λ₯Ό ꡬ해 μ΅œμ’… k번째 숫자 κ΅¬ν•˜κΈ°
			int q = (k - underKDigits) / (underKPlace + 1);   // λͺ«
            int r = (k - underKDigits) % (underKPlace + 1);   // λ‚˜λ¨Έμ§€
			Integer target = ((int) Math.pow(10, underKPlace) - 1) + q;
			if (r == 0) {
				System.out.println(Integer.toString(target).charAt(underKPlace));   // 수의 λ§ˆμ§€λ§‰ 인덱슀 μ ‘κ·Ό
			} else {
				System.out.println(Integer.toString(++target).charAt(--r));   // λ‚˜λ¨Έμ§€κ°€ μ‘΄μž¬ν•  경우 target λ‹€μŒ μˆ˜μ—μ„œ μΈλ±μ‹±ν•˜μ—¬ μ ‘κ·Ό
			}
		}
	}
}

πŸ’‘

  • μˆ˜ν•™ λ¬Έμ œλ“€μ€ 풀닀보면 λ­”κ°€ κ²Έμ†ν•΄μ§€λŠ” λŠλ‚Œβ€¦γ…Žγ…Ž
  • 자리수 별 숫자 개수λ₯Ό κ΅¬ν•˜λŠ” κ·œμΉ™λ§Œ 찾으면 κ·Έ λ‹€μŒμ€ κ΅¬ν˜„ 문제~~
  • 풀이λ₯Ό μžμ„Έν•˜κ²Œ μ •λ¦¬ν•˜λ‹ˆκΉŒ μ‹œκ°„μ€ μ˜€λž˜κ±Έλ¦¬μ§€λ§Œ ν™•μ‹€νžˆ λ¨Έλ¦¬μ—μ„œ 정리가 λœλ‹€.