반례입니다.
11653번 - 소인수분해
1. 우선 이 문제의 경우 사실 에라토스테네스의 체를 안쓰셔도 됩니다. (1부터 n/2 까지 1씩 증가시키면서 나누어 떨어질때마다 출력 하는 식으로)
2. 에라토스테네스의 체를 쓰신다면 sqrt(n) 까지만 확인해보셔도 됩니다. 이에 대한 증명도 알고싶으시면 제 블로그 글 중에 써둔게 있습니다.
1. 1씩 증가시키면서 만약 n이 999만대의 소수라면 약 499만번 나누게 되는건가요?
-> 넹. 사실 아래와 같은 코드만으로도 통과 가능합니다. (제가 파이썬은 잘 몰라서 좀 비효율적인 코드 있더라도 이해해주세요)
import sys input = sys.stdin.readline n = int(input()) for i in range(2, n+1): while n%i == 0: print(i) n//=i if n==1: break
결국 에라토스테네스의 체가 효율적인 부분은 만약 N이 여러번 들어온다고 생각하면, 미리 최대 수치의 N까지 에라토스테네스의 체로 계산해두고 연산하면 이득이긴 합니다. 하지만 이 문제와 같은 경우 어차피 N이 한 번 들어오므로 에라토스테네스의 체가 그리 효율적으로 보이진 않습니다. 그래도 후보군을 미리 소수를 구해서 좀 더 적은 범위로 만들고, 그걸로 나눠보는 아이디어 자체는 매우 좋은 것 같아요.
2. 그.. 블로그를 봐도 이해가 잘 안됩니다... 만약 n이 17이라면 4.? 가 제곱근일테고 그럼 에라토스로 걸러낸 소수로 나눌때 4.?보다 작은 2,3 만 가지고도 n이 소수인지 알 수 있는건가요?? 수학에 있어서 한눈에 들어오지 않아서 초등학생 가르쳐주듯이 천천히 설명 한번만 해주시면 정말 감사하겠씁니다 ㅠㅠㅠㅠ
-> 윗분이 추가로 설명해주셨네요! 네네 17이라면 4.x 정도일테니 4까지만 보면 됩니다.
그러니까 어떠한 수 n은 자연수 a, b에 대해 a * b라고 표현할 수 있어요. 그리고 또 m = sqrt(n) 이라 한다면 m * m도 n이라고 할 수 있죠.
따라서 a * b == m * m 이라고 할 수 있어요. 그럼 이 상태에서 나올 수 있는 경우는 다음의 세가지 입니다.
A. a=m, b=m (그럼 m도 자연수 였어야 겠죠.)
B. a>m, b<m
C. a<m, b>m
그럼 위 세가지 경우를 다 살펴보면 결국 min(a,b) <= m 인것을 알 수 있어요.
즉, n의 약수인 a와 b가 어떠한 것일지라도 둘 중 하나는 무조건 m(=sqrt(n))보다 작거나 같아요. 그러니 sqrt(n) 까지만 조사한다면 n이 소수인지 아닌지는 알 수 있게 되는거에요.
그럼 이건 n 단 하나에 대한 것이 아니냐고 하실 수 있는데, 결국 n 미만의 모든 자연수들은 n보다 작잖아요? 예를들어 n보다 작은 것 중 가장 큰 수인 n-1 조차도 어쨌든 sqrt(n) > sqrt(n-1) 이거든요. 그러니 n 이하의 모든 자연수에 대해 sqrt(n)까지만 보면 소수 판별이 가능한거죠.
댓글을 작성하려면 로그인해야 합니다.
cyaninn 2년 전 1
제 깃입니다
https://github.com/cyanindy/ba...
소인수분해니까 소수리스트를 구해서 나눠나가면 되겠다고 생각해서
에라토스테네스의 체로 소수리스트를 구하고
계속 나눠나가서 몫이 1이되면 반복이 끝나도록 했는데요
주피터에서 왠만한 짝수를 다 넣어봐도 잘 나오고
이전에 n의 제곱근을 활용해 조건을 걸고 돌렸을땐 틀렸습니다가 아니라 시간초과가 나왔는데...
리스트를 만드는 방식만 바뀌었는데 틀렸습니다가 나오는 이유를 모르겠습니다...