λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
μ•Œκ³ λ¦¬μ¦˜

[DFS] μž¬κ·€μ™€ μŠ€νƒμœΌλ‘œ κ°€λ³κ²Œ 문제 ν’€κΈ°

by μ„œμ•„λž‘πŸ˜ 2025. 5. 16.

 

λ“€μ–΄κ°€λ©°

μ €λ²ˆ ν¬μŠ€νŒ…μ—μ„œλŠ” 이전 μƒνƒœλ₯Ό κΈ°μ–΅ν•΄μ•Όν•˜λŠ” λ¬Έμ œκ°€ λŒ€ν‘œμ μΈ μŠ€νƒ ν™œμš©λ²•μ΄λΌκ³  μ†Œκ°œν–ˆμŠ΅λ‹ˆλ‹€.(이전 ν¬μŠ€νŒ…) μŠ€νƒκ³Ό μž¬κ·€λŠ” μ΄λŸ¬ν•œ μ μ—μ„œ λΉ„μŠ·ν•œ 점이 λ§ŽμŠ΅λ‹ˆλ‹€. 깊게 νŒŒκ³ λ“€μ–΄κ°”λ‹€κ°€ λ‹€μ‹œ λ‚˜μ˜€λŠ” ν˜•νƒœλŠ” λ™μΌν•˜μ£ . μ˜€λŠ˜μ€ μ΄λŸ¬ν•œ μœ ν˜•μ˜ 문제λ₯Ό μ ‘ν–ˆμ„ λ•Œ, μž¬κ·€λ₯Ό 선택해야 ν•˜λŠ”μ§€ μŠ€νƒμ„ μ„ νƒν•΄μ•Όν•˜λŠ”μ§€ μ•Œμ•„λ΄…μ‹œλ‹€.

κΈ°μ€€ μŠ€νƒ 기반 DSF μž¬κ·€ DFS
μ½”λ“œ λ³΅μž‘λ„ μŠ€νƒ μ„ μ–Έ, 쌍(pair) 관리, 반볡문 μ‚¬μš© ν•¨μˆ˜ 호좜둜 ꡬ쑰 λ‹¨μˆœ
가독성 흐름을 따라가기 어렀움 λ…Όλ¦¬μ μœΌλ‘œ 단계적이며 μžμ—°μŠ€λŸ¬μ›€
μ„±λŠ₯ λΉ„μŠ·ν•¨ (N이 μž‘μŒ, μ΅œλŒ€ 8자리) 거의 차이 μ—†μŒ
μ •λ ¬ ν›„μ²˜λ¦¬ ν•„μš” (벑터 + μ •λ ¬) 탐색 μˆœμ„œ 쑰절 κ°€λŠ₯ (forλ¬Έ μ˜€λ¦„μ°¨μˆœμœΌλ‘œ)

저도 λ””λ²„κΉ…μ˜ λ‚œν•΄ν•¨κ³Ό 직관적이지 μ•Šμ€ μ½”λ“œ 흐름 λ•Œλ¬Έμ— μž¬κ·€λ₯Ό μ™Έλ©΄ν•˜κ³€ ν–ˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ λŒ€λΆ€λΆ„μ˜ DFS λ¬Έμ œλŠ” μž¬κ·€λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 νŽΈν•˜λ‹€κ³  ν•©λ‹ˆλ‹€. λ‹€λ§Œ μž¬κ·€μ˜ κΉŠμ΄κ°€ 1만 λ…Έλ“œ μ΄μƒμœΌλ‘œ κΉŠμ–΄μ‘Œμ„ λ•ŒλŠ” ν•¨μˆ˜ μŠ€νƒ μ˜€λ²„ν”Œλ‘œκ°€ λ‚˜μ˜¬ 수 μžˆμœΌλ―€λ‘œ μŠ€νƒμ„ μ‚¬μš©ν•΄μ•Όν•©λ‹ˆλ‹€. λ˜ν•œ 이전 μƒνƒœμ˜ ꡬ쑰와 μ €μž₯ 방식이 λ‹¨μˆœν•˜μ§€ μ•Šμ€ κ²½μš°μ—λŠ” 데이터λ₯Ό λ”°λ‘œ λ§Œλ“€μ–΄μ„œ μŠ€νƒμ„ ν™œμš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ‹€λ§Œ μ•Œκ³ λ¦¬μ¦˜ μ½”λ”©ν…ŒμŠ€νŠΈμ˜ 경우 이런 κ²½μš°λŠ” 거의 μ—†κΈ° λ•Œλ¬Έμ— μž¬κ·€λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 νŽΈν•˜λ©°, μ‹€λ¬΄κ΄€μ μ—μ„œλŠ” μš”κ΅¬μ‚¬ν•­μ΄ λ³΅μž‘ν•˜κΈ° λ•Œλ¬Έμ— μŠ€νƒμ„ ν™œμš©ν•˜λŠ” 것이 쒋을 것 κ°™μŠ΅λ‹ˆλ‹€.

 

문제

λ°±μ€€ 2023: μ‹ κΈ°ν•œ μ†Œμˆ˜

자리수λ₯Ό μ€„μ—¬κ°€λ©΄μ„œ 얻은 μˆ«μžκ°€ λͺ¨λ‘ μ†Œμˆ˜μΈ 수λ₯Ό μ°ΎλŠ” λ¬Έμ œμž…λ‹ˆλ‹€. N의 μ΅œλŒ€κ°’μ΄ 8μ΄λΌμ„œ μž‘λ‹€κ³  λŠλ‚„μˆ˜ μžˆμ§€λ§Œ 천만 λ‹¨μœ„μž…λ‹ˆλ‹€. 문제 μ ‘κ·Ό 방식은 κ°€μž₯ 큰 μžλ¦¬μˆ˜λΆ€ν„° μ†Œμˆ˜μΈμ§€ ν™•μΈν•˜κ³  κ·Έ λ‹€μŒ 자리수λ₯Ό νƒμƒ‰ν•΄λ‚˜κ°€μ•Όν•©λ‹ˆλ‹€. 이전 μžλ¦Ώμˆ˜κ°€ μ†Œμˆ˜μΈμ§€λ₯Ό κΈ°μ–΅ν•΄μ•Όν•˜κΈ° λ•Œλ¬Έμ— DFS λ°©μ‹μœΌλ‘œ ν’€κ² μŠ΅λ‹ˆλ‹€.

 

풀이

ν’€μ΄λŠ” 두 κ°€μ§€ λ°©λ²•μœΌλ‘œ ν’€μ–΄λ΄€μŠ΅λ‹ˆλ‹€. 첫 λ²ˆμ§ΈλŠ” μŠ€νƒ, λ‘λ²ˆμ§ΈλŠ” μž¬κ·€μž…λ‹ˆλ‹€.

풀이1(μŠ€νƒ)

풀이 κ³Όμ •

  • μ†Œμˆ˜μΈμ§€ νŒλ³„ν•˜λŠ” ν•¨μˆ˜ μž‘μ„±(이건 νŒ¨ν„΄ν™” λ˜μ–΄ 있기 λ•Œλ¬Έμ— μ—¬κΈ°μ„œ 닀루지 μ•Šκ² μŠ΅λ‹ˆλ‹€, μ €λŠ” μ œκ³±κ·Όμ„ ν™œμš©ν•œ 방식 채택)
  • κ°€μž₯ 큰 자리 수 λ¨Όμ € μŠ€νƒμ— λ„£κΈ°(2, 3, 5, 7)(ν•œμžλ¦¬μˆ˜ μ†Œμˆ˜)
  • ν•˜λ‚˜μ”© λΉΌμ„œ λ‹€μŒ 수(next)κ°€ μ†Œμˆ˜μ΄λ©΄, λ‹€μ‹œ μŠ€νƒμ— λ„£κΈ°(5인 경우 λ‹€μŒμˆ˜λŠ” 51, 53, 55... -> μ§μˆ˜λŠ” μ†Œμˆ˜κ°€ μ•„λ‹˜)
  • μžλ¦¬μˆ˜κ°€ μž…λ ₯받은 μžλ¦¬μˆ˜μ™€ κ°™μœΌλ©΄ result λ¦¬μŠ€νŠΈμ— λ„£κΈ°
  • μŠ€νƒμ΄ λͺ¨λ‘ λΉ„μ–΄μžˆμ„ λ•ŒκΉŒμ§€ μœ„ λ‚΄μš© 반볡
  • result 리슀트 μ •λ ¬ 및 좜λ ₯
// c++ 17
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <math.h>
#include <algorithm>
using namespace std;


bool isPrime(int n)
{
    if (n <= 1) {
        return false;
    }

    for (int i = 2; i <= sqrt(n); i++) {
        if ((n%i) == 0) {
            return false;
        }
    }

    return true;
}

int main() 
{
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);

    int N;
    cin >> N;

    stack<int> s;
    vector<int> inputs{ 2, 3, 5, 7 };
    for (const auto i : inputs)
        s.push(i);

    vector<int> result;
    while (!s.empty())
    {
        const auto target = s.top();
        s.pop();

        if (to_string(target).size() == N)
        {
            result.push_back(target);
            continue;
        }

        for (int i = 1; i <= 9; i += 2)
        {
            const int num = target * 10 + i;
            if (isPrime(num))
                s.push(num);
        }
    }

    sort(result.begin(), result.end());
    for (const auto& r : result)
        printf("%d\n", r);
}

2,3,5,7 μˆœμ„œλŒ€λ‘œ μŠ€νƒμ— λ„£μ—ˆκΈ° λ•Œλ¬Έμ— 7393이 κ°€μž₯ λ¨Όμ € μŠ€νƒμ— λ“€μ–΄κ°‘λ‹ˆλ‹€. μžμ„Ένžˆ λ“€μ—¬λ‹€ λ³΄κ² μŠ΅λ‹ˆλ‹€. κ°€μž₯λ¨Όμ € 7이 λ‚˜μ˜€κ³ , 71은 μ†Œμˆ˜κ°€ μ•„λ‹˜, λ‹€μŒ 73은 μ†Œμˆ˜μ΄κΈ° λ•Œλ¬Έμ— 73 μŠ€νƒ μ‚½μž…ν•©λ‹ˆλ‹€. λ‹€μ‹œ 73 κΊΌλ‚΄μ„œ κ·Έ λ‹€μŒ 자리수 λΉ„κ΅ν•˜λ©΄ 733, 739κ°€ μ°¨λ‘€λ‘œ μŠ€νƒμ— μ‚½μž…λ©λ‹ˆλ‹€. λ‹€μ‹œ 739λ₯Ό κΊΌλ‚΄κ³  λ§ˆμ§€λ§‰ 자리수λ₯Ό λΉ„κ΅ν•˜λ©΄ 7393이 νƒ€κ²Ÿμ΄ λ˜μ–΄ result에 λ“€μ–΄κ°‘λ‹ˆλ‹€.

 

풀이2(DFS)

풀이 κ³Όμ •

  • numκ³Ό digit을 인자둜 λ°›λŠ” DFS ν•¨μˆ˜λ₯Ό λ§Œλ“œλŠ” 것이 ν‚€ν¬μΈνŠΈ
  • μž¬κ·€ν•¨μˆ˜λŠ” 항상 λΉ μ Έλ‚˜κ°ˆ ꡬ멍 λ¨Όμ € λ§Œλ“­μ‹œλ‹€.
  • 자리수(digit) 쑰건이 λ§Œμ‘±ν•˜κ³ , μ†Œμˆ˜μ΄λ©΄ 좜λ ₯ ν›„ ν•¨μˆ˜ μ’…λ£Œ
  • nextκ°€ μ†Œμˆ˜μ΄λ©΄ μž¬κ·€ν˜ΈμΆœ(digit이 λŠ˜μ–΄λ‚¬κΈ° λ•Œλ¬Έμ— digit+1둜 호좜)
  • mainμ—μ„œλŠ” 첫번째 자리수 νƒ€κ²Ÿ(2,3,5,7) 만큼 DSFν•¨μˆ˜ 호좜
// C++ 17
#include <iostream>
#include <vector>
using namespace std;
int N;

bool isPrime(int num) {
     if (n <= 1) 
        return false;

    for (int i = 2; i <= sqrt(n); i++) {
        if ((n%i) == 0) 
            return false;
    }

    return true;
}

void DFS(int num, int digit)
{
    if (digit == N)
    {
        if (isPrime(num))
        {
            cout << num << endl;
            return;
        }
    }

    for (int i = 1; i < 10; i += 2)
    {
        int next = num * 10 + i;
        if (isPrime(next))
            DFS(next, digit + 1);
    }
}

int main()
{
    cin >> N;
    DFS(2, 1);
    DFS(3, 1);
    DFS(5, 1);
    DFS(7, 1);
}

DFS둜 ν‘Ό μ½”λ“œκ°€ 훨씬 κ°„κ²°ν•©λ‹ˆλ‹€.

 

정리

였늘 λ¬Έμ œλŠ” μ „ν˜•μ μΈ μž¬κ·€ DSF λ§žμΆ€μ΄μ—ˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ μ €λŠ” μ²˜μŒλΆ€ν„° μŠ€νƒμ„ μ“°λ €κ³  κ³ μ§‘ν–ˆμŠ΅λ‹ˆλ‹€. μŠ€νƒμ΄λ“  μž¬κ·€λ“  잘 ν’€λ©΄ λ˜μ§€λ§Œ 더 μžμ—°μŠ€λŸ¬μš΄ 방법을 μ±„νƒν•˜λŠ” 것이 생산성에 도움이 λ©λ‹ˆλ‹€. 문제λ₯Ό 처음 μ ‘ν–ˆμ„ λ•Œ μžμ—°μŠ€λŸ½κ³  κ°„κ²°ν•˜κ²Œ ν’€ 수 μžˆλŠ” 방법을 찾으렀고 κΎΈμ€€νžˆ λ…Έλ ₯ν•΄λ΄…μ‹œλ‹€.

λŒ“κΈ€