Home 백준 - 1929 소수 구하기 풀이
Post
Cancel

백준 - 1929 소수 구하기 풀이

문제

1929 소수 구하기

screencapture

소수란?

  • 소수(素數, 발음: [소쑤], 문화어: 씨수, 영어: prime number)는 1보다 큰 자연수 중 1과 자기 자신만을 약수로 가지는 수다.[소수 (수론)]

소수 판별 방법

풀이

개념

  • 특정 수가 소수인지를 판별하기 위해서는 1보다 크고 자기 보다 작은 모든 수로 자기 자신을 나눴을 때 나머지가 없는 수가 있는지 확인하면 된다.
    1
    2
    3
    4
    5
    
    fun Int.isPrimeNum(): Boolean {
      for(i in 2 until this)
          if(this % i == 0) return false
      return true
    }
    

    최적화

  • 정말 “1보다 크고 자기 보다 작은 모든 수”를 대상으로 확인을 해야 할까?
  • 사실 어떤 자연수 n이 소수임을 판정하기 위해서 ⌊√n⌋까지만 진행하면 되는데, 수가 수를 나누기 위해서는 그 몫이 항상 필요하며 나누는 수와 몫 중 어느 하나는 반드시 √n이하이기 때문이다.[소수 (수론)]

    예)

    1. 64의 약수는 1, 2, 4, 8, 16, 32, 64 이다. 즉, 64 = 1 * 64 = 2 * 32 = 4 * 16 = 8 * 8 이다. 즉, 2, 4, 8만을 대상으로 확인하면 소수인지 여부가 판별이 가능하다. 2, 4, 8은 모두 ⌊√64⌋ = 8 이하이다.
    2. 90의 약수는 1, 2, 3, 5, 6, 9, 10, 15, 18, 30, 45, 90 즉, 90 = 1 * 90 = 2 * 45 = 3 * 30 = 5 * 18 = 6 * 15 = 9 * 10 즉, 2, 3, 5, 6, 9 만으로 대상으로 확인하면 소수인지 여부가 판별이 가능하다. 2, 3, 5, 6, 9는 모두 ⌊√90⌋ = 9 이하이다.
  • “1보다 크고 자기 보다 작은 모든 수” 즉, (n - 2)번이 아닌 ⌊√n⌋번의 연산만 하면 된다.

    예) n = 97일 경우 95번(2 until 97)의 연산이 아닌 8번(2 .. 9)의 연산만 하면 된다.

    1
    2
    3
    4
    5
    6
    
    fun Int.isPrimeNum(): Boolean {
      val other = kotlin.math.sqrt(this.toDouble()).toInt()
      for(i in 2..other)
          if(this % i == 0) return false
      return true
    }
    

kotlin code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fun main() {
    val input = readln().split(" ").map { it.toInt() }
    for(i in input[0] .. input[1])
    {
        if(i.isPrimeNum()) println(i)
    }
}

fun Int.isPrimeNum(): Boolean {
    if(this < 2) return false
    if(this == 2) return true
    val other = kotlin.math.sqrt(this.toDouble()).toInt()
    for(i in 2..other)
        if(this % i == 0) return false
    return true
}

에라토스테네스의 체 방법

풀이

에라토스테네스의 체 알고리즘

1
2
3
4
1. 찾고자 하는 범위의 자연수를 나열한다.
2. 1은 지운다.
3. 2부터 시작하여, 2의 배수를 지워나간다.
4. 다음 소수의 배수를 모두 지운다. [[소수 (수론)](https://ko.wikipedia.org/wiki/%EC%86%8C%EC%88%98_(%EC%88%98%EB%A1%A0))]

kotlin code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
fun main() {
    val input = readln().split(" ").map { it.toInt() }
    val isPrimeNumbers = BooleanArray(input[1] + 1) { true }
    isPrimeNumbers[0] = false
    isPrimeNumbers[1] = false
    val limitNumber = kotlin.math.sqrt(input[1].toDouble()).toInt()

    for(number in (2..limitNumber))
    {
        if(!isPrimeNumbers[number]) continue
        val powerOfNumber = number * number
        for (y in (powerOfNumber until isPrimeNumbers.size) step number) {
            isPrimeNumbers[y] = false
        }
    }

    for(i in (input[0]..input[1])) {
        if(isPrimeNumbers[i]) println(i)
    }
}

Reference

This post is licensed under CC BY 4.0 by the author.

백준 - 4948 베르트랑 공준

백준 - 24479 알고리즘 수업 - 깊이 우선 탐색 1