opr8632   4년 전

8 번째 줄까지 에라토스테네스의 체를 활용하여 소수 리스트를 생성한후 마지막줄 주석설명과 같은 논리에 의해  코딩을 해보았습니다. 여려가지 예제를 테스트해보았고 성공했으나 채점시엔 바로 틀렸습니다라고 나오는데 반레가 무엇인지 모르겠습니다. 질문게시판을 뒤지다가 소수 리스트의 공간을 충분히 주면 성공한 사례들을 보고 n 값을 크게 주어 보아도 실패입니다. 도와주세요 ㅠ 

dongdhy   4년 전

15번째 줄처럼 조건문을 작성하시면 j가 0이 아니고 x-j가 소수리스트에 있으면 참이라고 인식됩니다. 따라서 해당 경우에는 j in p_list and x-j in p_list로 표현하는게 바람직하며 그 외 추가적으로 수정이 지향되는 부분들에 대해 말씀드리겠습니다. 어떤 수가 소수인지 검사하기 위해서는 2~해당수의 제곱근까지 그 수가 나뉘어지지않으면 그 수는 소수입니다. 그런데 4번째 for문의 범위를 보면 n + 1까지 for문을 돌리고 있습니다. 아마 질문자분도 방금 말씀드린 규칙에 대해서는 인지하셔서 **0.5를 넣으신 것 같은데 원하시는 결과를 얻으시려면 int(n**0.5)+1을 하셨어야합니다. 또한 이미 해당 수가 소수인지 아닌지 여부를 판별시켜주는 a리스트가 있기때문에 굳이 이 문제에서는 소수리스트를 만드실 필요가 없습니다. 오히려 x가 소수인지 확인하기 위해서 a[x]로 O(1)로 해결되었을 문제가 in연산 사용시 O(n)까지 증가해버립니다. 또한 지금은 문제가 없지만 for문 범위 정정시 10000의 제곱근 이후로는 p_list에 들어갈 수 없습니다. 따라서 더더욱 소수리스트가 등장하면 안됩니다.

opr8632   4년 전

친절한 답변 정말 감사드립니다!

'15번째 줄처럼 조건문을 작성하시면 j가 0이 아니고 x-j가 소수리스트에 있으면 참이라고 인식됩니다. 따라서 해당 경우에는 j in p_list and x-j in p_list로 표현하는게 바람직하며'라고  답변해주신 부분을 보고 무엇이 잘못되었는지 알게 되어  j in p_list and x-j in p_list로 수정해 제출했더니 정답처리되었습니다.

추가로 제가 문제를 편리하게 풀기위해 추가로 생성한 소수리스트에 대한 조언도 감사드립니다만 a리스트는 인덱스값이 k 이면 k가 소수인지 아닌지를 true 와 false로 표현한 리스트이므로 int(n+1**0.5)을 int(n**0.5)+1로 수정하면 틀리게 되는거 같습니다. (a[5]가 'True'요소를 가지는 것은 자연수 4가아닌 자연수5가 소수라는 의미의 리스트) 또한, 제가 a리스트를 생성할때 정수 0 과 자연수 1만 소수가아닌 'False'를 입력하고 뒤의 자연수는 전부 초기값을 'True'로 줌에 따라서 답변자님께서 마지막줄에 언급해주신 for문 범위 정정시에도 10000의 제곱근 이후값도 p_list 에 들어가게 되더군요

다만 시간복잡도 면에서 상당히 비효율적인 코드라는 점을 알려주셔서 이에따라 a리스트만으로 문제를 하결하는 법을 더 공부해서 풀어보겠습니다 감사합니다!

dongdhy   4년 전

int(n+1**0.5)을 int(n**0.5)+1로 수정하면 틀리게 되는거 같습니다라고 말씀하셨는데 무슨 말씀이신지 잘 모르겠네요. 위에 말씀드렸다시피 어떠한 수 n이 소수인지 판별하기 위해서는 그 제곱근이하의 모든 소수에 의해서 나누어떨어지면 안됩니다. 즉 2이상 n의제곱근 이하의 어떤 소수로도 n이 나누어떨어지지않는다면 n은 소수입니다. 따라서 n의 최대값이 10000인 경우 2부터 100로만 나누어봐도 10000까지의 수가 소수인지 여부를 알 수 있습니다.  따라서
for i in range(2, int(n**0.5)+1):

    if a[i]:

        for j in range(2*i, n+1, i):

            a[j] = False

라는 코드 후에 a의 인덱스에 10000이하의 수를 넣으면 해당수가 소수인지 아닌지 여부를 알 수 있습니다. 그리고 for문 범위를 변경해도 10000의 제곱근 이후의 값이 p_list에 들어간다고 말씀하셨는데 p_list에 원소를 추가하는 문장은 for문 안에 존재하며 해당 문장은 2~100까지만 돌아가기때문에  for문 range end범위를 int(n**0.5)+1로 변경시 101이후로는 소수리스트에 들어갈 수 없는게 맞습니다.

댓글을 작성하려면 로그인해야 합니다.