λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

Algorithm/이둠

[μ•Œκ³ λ¦¬μ¦˜] 8의 개수 κ΅¬ν•˜κΈ° (1~10μ–΅)

8의 개수 κ΅¬ν•˜κΈ° (1~10μ–΅) C++

ꡬ글 μž…μ‚¬λ¬Έμ œ

ꡬ글 μž…μ‚¬ 문제 쀑, 1λΆ€ν„° 100000 사이인 N이 주어지고, 1λΆ€ν„° NκΉŒμ§€μ˜ μˆ˜μ—μ„œ 8이 λ‚˜μ˜€λŠ” 횟수λ₯Ό 좜λ ₯ν•˜λŠ” λ¬Έμ œκ°€ μžˆλ‹€.

μ—¬κΈ°μ„œ 88μ΄λΌλŠ” μˆ«μžκ°€ 있으면, 88은 8이 두 개 λ“€μ–΄κ°€λ―€λ‘œ, 2둜 μΉ΄μš΄νŠΈν•΄μ•Ό λœλ‹€.

N이 μ΅œλŒ€ 10만이기 λ•Œλ¬Έμ—, 10만의 μžλ¦¬μˆ˜λŠ” 6μ΄λ―€λ‘œ, μ΅œμ•…μ˜ μ‹œκ°„ λ³΅μž‘λ„λ‘œ 생각해도 60만이 λœλ‹€.

λ”°λΌμ„œ μ—¬λŸ¬ 가지 풀이듀이 μžˆκ² μ§€λ§Œ, 각 숫자λ₯Ό μˆœνšŒν•˜λ©΄μ„œ 각 숫자의 자리수λ₯Ό ν•˜λ‚˜ν•˜λ‚˜ 확인해도 1초 μ•ˆμ— μΉ΄μš΄νŠΈκ°€ κ°€λŠ₯ν•˜λ‹€.

10μ–΅μœΌλ‘œ ν™•μž₯

N이 1λΆ€ν„° μ΅œλŒ€ 10μ–΅κΉŒμ§€λΌκ³  주어진닀면 문제λ₯Ό μ–΄λ–»κ²Œ ν’€μ–΄μ•Ό ν• κΉŒ?

9μ–΅κΉŒμ§€λΌκ³ λ§Œ 해도 9μ–΅ * 9μ–΅μ˜ 자리수이기 λ•Œλ¬Έμ— λ‹¨μˆœν•˜κ²Œ μ™„μ „ 탐색을 ν•˜λ©΄ μ‹œκ°„ μ΄ˆκ³Όκ°€ λœλ‹€.

μ™„μ „ 탐색이 μ•„λ‹Œ 효율적인 방법을 μ°Ύμ•„μ•Ό ν•œλ‹€.

ν•΄κ²° 방법

ν™•μž₯된 문제λ₯Ό ν‘ΈλŠ” 방법은, 각 자리 μˆ˜λ§ˆλ‹€ λ‚˜λˆ μ„œ 8이 λ“±μž₯ν•˜λŠ” 횟수λ₯Ό ꡬ해야 ν•œλ‹€.

예λ₯Ό λ“€μ–΄ N이 4자리의 수 라면, 경우λ₯Ό 4κ°€μ§€λ‘œ λ‚˜λˆˆ λ’€ 횟수λ₯Ό λ”ν•΄μ€˜μ•Ό ν•œλ‹€.

μ΄λ•Œ ν•œμžλ¦¬ ν•œμžλ¦¬λ§ˆλ‹€ 확인할 λ•Œ, κ·Έ ν•œ 자릿수λ₯Ό μ„Έ 가지 경우둜 λ‚˜λˆ μ•Ό ν•œλ‹€.

 

8 보닀 μž‘μ„ λ•Œ
8 일 λ•Œ
8 보닀 클 λ•Œ

 

μ„Έ 가지 경우둜 λ‚˜λˆˆ λ’€, ν•΄λ‹Ήν•˜λŠ” 자리수의 μ™Όμͺ½ μˆ˜λ“€κ³Ό 였λ₯Έμͺ½ 수 듀을 ν™•μΈν•˜κ³  μΉ΄μš΄νŠΈν•˜λŠ” λ°©μ‹μœΌλ‘œ ν•΄κ²°ν•œλ‹€.

8 보닀 μž‘μ„ λ•Œ

52723μ΄λΌλŠ” μˆ«μžκ°€ 있고, μ„Έ 번째 μžλ¦¬μ—μ„œ 8이 λͺ‡ 번 λ‚˜μ˜¬ 수 μžˆλŠ”μ§€ ν™•μΈν•œλ‹€κ³  ν•˜μž.

52xxx 일 λ•ŒλŠ”, μ„Έ 번째 μžλ¦¬μˆ˜κ°€ 7μž„μœΌλ‘œ 8이 λ“±μž₯ν•  수 μ—†λ‹€.

008.., 018.., 028.., ... 518..κΉŒμ§€ μ•žμ˜ 수λ₯Ό ν™•μΈν•˜λ©΄ 총 0~51κΉŒμ§€κΉŒμ§€ 52의 경우의 μˆ˜κ°€ λ‚˜μ˜¨λ‹€.

8λ’€μ˜ .. 은 0λΆ€ν„° 99κΉŒμ§€ 총 100κ°€μ§€μ˜ 경우의 μˆ˜κ°€ λ‚˜μ˜¨λ‹€. 결과적으둜 52*100
즉, (μ•žμžλ¦¬ 수) * 10^λ’·μžλ¦¬μˆ˜λ₯Ό 더해야 ν•œλ‹€.

8 일 λ•Œ

μ•žμ—μ„œ 8보닀 μž‘μ„ λ•Œμ—μ„œ 528..κΉŒμ§€ μΉ΄μš΄νŠΈκ°€ λ˜λ―€λ‘œ 8보닀 μž‘μ„ λ•Œμ˜ 경우의 μˆ˜μ—μ„œ,

λ’€μ˜ ..μ—μ„œ λ‚˜μ˜¬ 수 μžˆλŠ” 경우의 수인 0~ λ’·μžλ¦¬ 수 -> λ’·μžλ¦¬ 수 + 1의 경우의 수λ₯Ό 더해야 ν•œλ‹€.

즉 (μ•žμžλ¦¬ 수) * 10^λ’·μžλ¦¬μˆ˜ + λ’·μžλ¦¬ 수+1을 더해야 ν•œλ‹€.

8 보닀 클 λ•Œ

8 보닀 클 λ•ŒλŠ” 529.. μž„μœΌλ‘œ 528..둜 μ‹œμž‘ν•˜λŠ” λͺ¨λ“  수λ₯Ό 더할 수 μžˆλ‹€.

즉 0~52κΉŒμ§€μΈ 경우의 μˆ˜λŠ” 52+1μ΄λ―€λ‘œ (μ•žμžλ¦¬ 수+1) * 10^λ’·μžλ¦¬μˆ˜λ₯Ό 더해야 λœλ‹€.

μ†ŒμŠ€μ½”λ“œ

#include <iostream>
using namespace std;
long long result;
long long sumResult(int leftNum, int rightNum, int swc, int digit);
int main(void) {
    int N;
    cin >> N;
    int rightNum = 0;
    int leftNum = N;
    int nowdigit = 1;
    while (leftNum) {
        int lastNum = leftNum % 10;
        leftNum /= 10;
        int swc;
        if (lastNum < 8) swc = -1;
        else if (lastNum == 8) swc = 0;
        else swc = 1;
        result += sumResult(leftNum, rightNum, swc, nowdigit);
        rightNum += lastNum * nowdigit;
        nowdigit *= 10;
    }
    cout << result << '\n';
    return 0;
}
long long sumResult(int leftNum, int rightNum, int swc, int digit) {
    if (swc == -1) {
        return leftNum * digit;
    }
    else if (swc == 0) {
        return leftNum * digit + rightNum + 1;
    }
    else {
        return (leftNum + 1) * digit;
    }
}

λͺ¨λ“  경우의 μˆ˜λ“€μ„ μ½”λ“œλ‘œ λ‚˜νƒ€λ‚΄λ©΄ μœ„μ™€ 같이 κ΅¬ν˜„ν•  수 μžˆλ‹€.