𝘚𝘭𝘰𝘸 𝘣𝘢𝘡 𝘴𝘡𝘦𝘒π˜₯𝘺

[λ°±μ€€] 1929번: μ†Œμˆ˜ κ΅¬ν•˜κΈ° - C++ (+ μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체) λ³Έλ¬Έ

μ½”λ”©ν…ŒμŠ€νŠΈ μ€€λΉ„/λ°±μ€€

[λ°±μ€€] 1929번: μ†Œμˆ˜ κ΅¬ν•˜κΈ° - C++ (+ μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체)

.23 2021. 8. 18. 03:39
문제

M이상 Nμ΄ν•˜μ˜ μ†Œμˆ˜λ₯Ό λͺ¨λ‘ 좜λ ₯ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

 

μž…λ ₯

첫째 쀄에 μžμ—°μˆ˜ Mκ³Ό N이 빈 칸을 사이에 두고 주어진닀. (1 ≤ M ≤ N ≤ 1,000,000) M이상 Nμ΄ν•˜μ˜ μ†Œμˆ˜κ°€ ν•˜λ‚˜ 이상 μžˆλŠ” μž…λ ₯만 주어진닀.

 

좜λ ₯

ν•œ 쀄에 ν•˜λ‚˜μ”©, μ¦κ°€ν•˜λŠ” μˆœμ„œλŒ€λ‘œ μ†Œμˆ˜λ₯Ό 좜λ ₯ν•œλ‹€.


μ•žμ„œ 1978번 μ†Œμˆ˜ μ°ΎκΈ°μ—μ„œ ν’€μ—ˆλ˜ νŠΉμ • μˆ˜μ— λŒ€ν•œ μ†Œμˆ˜ νŒμ •μ„ ν™•μž₯ν•˜μ—¬ νŠΉμ • λ²”μœ„ λ‚΄μ˜ μ†Œμˆ˜λ₯Ό λͺ¨λ‘ κ΅¬ν•˜λŠ” μ•Œκ³ λ¦¬μ¦˜μΈ μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체λ₯Ό μ΄μš©ν•˜μ—¬ ν’€ 수 μžˆλŠ” λ¬Έμ œμ΄λ‹€.

말이 μ–΄λ ΅μ§€λ§Œ, 원리가 κ°„λ‹¨ν•˜λ‹€. 2 μ΄μƒμ˜ κ΅¬ν•˜κ³ μž ν•˜λŠ” λ²”μœ„ 내에 μ‘΄μž¬ν•˜λŠ” μžμ—°μˆ˜λ₯Ό λͺ¨λ‘ λ‚˜μ—΄ν•œ λ’€, 2의 λ°°μˆ˜λΆ€ν„° 3의 배수, 4의 배수, ... λ“± μ°¨λ‘€λ‘œ κ·Έ 수의 λ°°μˆ˜λ“€μ„ μ§€μ›Œλ‚˜κ°„λ‹€.

 

예λ₯Ό λ“€μ–΄, λ‹€μŒκ³Ό 같이 2λΆ€ν„° 50κΉŒμ§€μ˜ λ²”μœ„ 내에 μ‘΄μž¬ν•˜λŠ” μ†Œμˆ˜λ₯Ό μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체λ₯Ό μ΄μš©ν•΄ ꡬ해보도둝 ν•œλ‹€.

1단계 : 2λ₯Ό μ œμ™Έν•œ 2의 배수λ₯Ό λͺ¨λ‘ μ œμ™Έν•œλ‹€.

2단계 : 3을 μ œμ™Έν•œ 3의 배수λ₯Ό λͺ¨λ‘ μ œμ™Έν•œλ‹€.

3단계 : 4의 λ°°μˆ˜λŠ” μ•žμ„œ 1λ‹¨κ³„μ—μ„œ λͺ¨λ‘ μ œμ™Έλ˜μ—ˆμœΌλ―€λ‘œ, 5λ₯Ό μ œμ™Έν•œ 5의 배수λ₯Ό λͺ¨λ‘ μ œμ™Έν•œλ‹€.

4단계 : μ•žμ„  단계듀과 λ§ˆμ°¬κ°€μ§€λ‘œ 아직 μ§€μ›Œμ§€μ§€ μ•Šμ€ 7의 배수, 11의 배수 .. 등을 μ§€μ›Œλ‚˜κ°€κ²Œ 되면 μœ„μ™€ 같이 μ΅œμ’…μ μΈ μ†Œμˆ˜λ“€μ΄ λ‚¨κ²Œ λœλ‹€.

λ”°λΌμ„œ 2와 50 사이에 μ‘΄μž¬ν•˜λŠ” μ†Œμˆ˜λŠ” 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47이닀.

 

μ½”λ“œλŠ” λ‹€μŒκ³Ό κ°™λ‹€. 2λΆ€ν„° NκΉŒμ§€μ˜ λ°°μ—΄μ—μ„œ 0으둜 기둝된 κ°’μ˜ μΈλ±μŠ€κ°€ 곧 μ†Œμˆ˜κ°€ λœλ‹€. μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체의 μ‹œκ°„λ³΅μž‘λ„λŠ” O(N log(log N))으둜 맀우 λΉ λ₯΄κ²Œ μž‘λ™ν•œλ‹€.

for(int i = 2; i * i <= N; i++) {
    if(arr[i] == 0) continue;	// 이미 μˆ˜κ°€ μ§€μ›Œμ§„ 경우 λ„˜μ–΄κ°
    for(int j = 2 * i; j <= N; j += i) {
    	if(arr[j] == 0)  continue;	// μ†Œμˆ˜κ°€ μ•„λ‹Œ 경우 λ„˜μ–΄κ°
        else arr[j] = 0;	// μ†Œμˆ˜λ₯Ό 지움
    }
}

 

+ 기본적으둜 μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체λ₯Ό μ΄μš©ν•˜μ—¬ 문제λ₯Ό ν’€μ—ˆλŠ”λ°, μ‹œκ°„ μ œν•œμ΄ λ„‰λ„‰ν•œκ²Œ ν˜Ήμ‹œλ‚˜ μ‹Άμ–΄ μ•žμ„œ κ΅¬ν•œ μ†Œμˆ˜ νŒμ • λ°©μ‹μœΌλ‘œ ν’€μ–΄λ΄€λŠ”λ° 톡과가 되긴 ν–ˆλ‹€.

 

μ½”λ“œ
#include <cstdio>
#include <vector>

using namespace std;

int main(void) {
    int m, n;
    scanf("%d %d", &m, &n);
    
    vector<int> arr(n + 1, 0);

    for(int i = 2; i <= n; i++) {
        arr[i] = i;
    }

    for(int i = 2; i * i <= n; i++) {
        if(arr[i] == 0) continue;
        for(int j = 2 * i; j <= n; j += i) {
            if(arr[j] == 0)  continue;
            else arr[j] = 0;
        }
    }

    for(int i = m; i <= n; i++) {
        if(arr[i] != 0) printf("%d\n", arr[i]);
    }
    return 0;
}
Comments