BOJ 2960 에라토스테네스의 체 풀이 #9

Description

@allzeroyou

문제 분석

첫 번째 단계(문제 요약 및 조건 파악)

에라토스테네스의 체: n보다 작거나 같은 모든 소수를 찾는 알고리즘.

  1. 2부터 n까지 모든 정수를 적는다
  2. 아직 지우지 않은 수 중 가장 작은 수 찾기. 이걸 p라고 하고, 이 수는 소수임.
  3. p를 지우고, 아직 지우지 않은 p의 배수를 크기 순서대로 지운다
  4. 아직 모든 수를 지우지 않았다면 다시 2번 단계로 간다.

n, k가 주어졌을 때 k번째 지우는 수를 구하는 프로그램 작성.

입력

  • n, k가 주어짐(1 ≤ K < N, max(1, K) < N ≤ 1000)

출력

  • k번째 지워진 수를 출력.

두 번째 단계 (문제 핵심 파악)

  1. 2~n까지 정수가 담긴 리스트를 만든다.
  2. 가장 작은 수를 p라고 할때, p는 소수임.
  3. p를 리스트에서 삭제하고, 리스트에 남아있는 p의 배수를 크기순으로 지운다.
  4. 이때, p가 1st, p의 배수 중 첫번째 요소가 2nd, p의 배수 중 2번째 요소가 3rd 순이다.
  5. 이때 리스트가 비어있지 않다면(while 리스트) 다시 2번으로 가서 단계를 지속한다.

코드 작성

importsysinput=sys.stdin.readlinen, k=map(int, input().split())
cnt=0# 순서 카운트# 2부터 n 까지lst= [iforiinrange(2, n+1)]
whilelen(lst) !=0:
# 가장 작은 수 : pmin_num=lst[0]
baesu_lst= []
forjinrange(len(lst)): # 2~7iflst[j] %lst[0] ==0:
# lst.remove(lst[j])baesu_lst.append(lst[j])
cnt+=1ifcnt==k:
print(baesu_lst[-1])
breakifcnt==k:
breaklst= [xforxinlstifxnotinbaesu_lst]

느낀점

첫번째 시도에서,

importsysinput=sys.stdin.readlinen, k=map(int, input().split())
cnt=0# 순서 카운트# 2부터 n 까지lst= [iforiinrange(2, n+1)]
whilelen(lst) !=0:
# 가장 작은 수 : pmin_num=lst[0]
baesu_lst= []
forjinrange(len(lst)): # 2~7iflst[j] %lst[0] ==0:
# lst.remove(lst[j])baesu_lst.append(lst[j])
cnt+=1ifcnt==k:
print(baesu_lst[-1])
breaklst= [xforxinlstifxnotinbaesu_lst]

if문을 for문 밖으로 빼서, cnt가 k와 같을때 멈춰야 하는데 그러지 못하고 계속 반복문을 돌았다.

따라서 if문을 for문 안으로 넣어서 for문의 종료조건을 만족시켰으며 if문을 밖으로 빼서 while 문의 종료조건을 만족시켰다.

리스트를 구할 때 위처럼 리스트 컴프리헨션을 이용하니 코드가 짧아진 데서 오는 안정감과 가독성이 있는거 같다.(유용하게 쓰자)

사실 첫번째 코드는 test case는 모두 통과해서 정답인줄 알았지만, 제출 시 17%에서 오답이었고, 반례를 찾는 실력까지는 도달을 못해서 chatGPT가 10 3 가 반례임을 제시해서 이를 이용해서 완전한 코드가 되었다.

반례 찾는 연습 해봐야지(어떻게?)

반례 찾기

(https://velog.io/@juyeonma9/%EB%B0%B1%EC%A4%80-%EC%9E%90%EC%A3%BC%ED%8B%80%EB%A6%AC%EB%8A%94%EC%9A%94%EC%9D%B8)

  • 가장 중요한 것은 직접 데이터를 만들어서 넣어 보는 것입니다.https://www.acmicpc.net/problem/14405 를 예로 들어 봅시다. 그러면 이런 입력들을 넣어 볼 수 있습니다.
    • pi 하나만 넣으면? ka? chu? 한 글자만 넣으면? p? k? c? i? a? r?
    • pika는 YES가 나와야 합니다. 이걸 조금 변형하면? pik? pia? pka? piak? pkia? ipka? kipa? pikaa? pikka? piika? ppika?
    • kapi도 YES가 나와야 합니다. 이걸 조금 변형하면? kap? kai? api? kaip? kpai? kapii? kaapi?
    • 주어진 예제를 조금 변형하면? pikap? pikpi? pipikach? pipikaphu?
    • 그냥 정말로 아무거나 넣으면? abcd? pipichukachuka? pichaku? ppap? pikach?
  • 입력으로 1 이상 1,000,000 이하의 정수 N이 주어진다면 N=1, N=2 등의 최소 케이스가 잘 나오는지 확인하는 것이 좋습니다. 이런 입력이 특이 케이스가 되는 문제들이 종종 있고, 굳이 특이 케이스가 아니더라도 우리의 코드가 최소 케이스에서 틀릴 가능성은 얼마든지 있습니다. 위에서 언급한 "피카츄" 문제의 경우 p, k 등의 한 글자짜리 입력이 여기에 해당되겠죠.
  • N=1,000,000 같은 최대 케이스를 넣었을 때 주어진 시간 제한 안에 답이 나오는지도 확인해 볼 수 있습니다. 답이 맞는지 확인하는 건 어떨까요? 문제에 따라 답을 손으로 알아내기 힘들 수도 있는데, 적어도 말이 되는 값은 나와야겠죠? 출력이 무조건 0 이상일 수밖에 없는 문제에서 음수가 나오면 뭔가 잘못되었다는 뜻입니다.

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentation

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
     blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
    }
    } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
    })();
    (function(){
    try {
    var __m = "github.com";
    var __re = new RegExp('^' + "github\\.com" + '
    
    Skip to content

    BOJ 2960 에라토스테네스의 체 풀이 #9

    Description

    @allzeroyou

    문제 분석

    첫 번째 단계(문제 요약 및 조건 파악)

    에라토스테네스의 체: n보다 작거나 같은 모든 소수를 찾는 알고리즘.

    1. 2부터 n까지 모든 정수를 적는다
    2. 아직 지우지 않은 수 중 가장 작은 수 찾기. 이걸 p라고 하고, 이 수는 소수임.
    3. p를 지우고, 아직 지우지 않은 p의 배수를 크기 순서대로 지운다
    4. 아직 모든 수를 지우지 않았다면 다시 2번 단계로 간다.

    n, k가 주어졌을 때 k번째 지우는 수를 구하는 프로그램 작성.

    입력

    • n, k가 주어짐(1 ≤ K < N, max(1, K) < N ≤ 1000)

    출력

    • k번째 지워진 수를 출력.

    두 번째 단계 (문제 핵심 파악)

    1. 2~n까지 정수가 담긴 리스트를 만든다.
    2. 가장 작은 수를 p라고 할때, p는 소수임.
    3. p를 리스트에서 삭제하고, 리스트에 남아있는 p의 배수를 크기순으로 지운다.
    4. 이때, p가 1st, p의 배수 중 첫번째 요소가 2nd, p의 배수 중 2번째 요소가 3rd 순이다.
    5. 이때 리스트가 비어있지 않다면(while 리스트) 다시 2번으로 가서 단계를 지속한다.

    코드 작성

    importsysinput=sys.stdin.readlinen, k=map(int, input().split())
    cnt=0# 순서 카운트# 2부터 n 까지lst= [iforiinrange(2, n+1)]
    whilelen(lst) !=0:
    # 가장 작은 수 : pmin_num=lst[0]
    baesu_lst= []
    forjinrange(len(lst)): # 2~7iflst[j] %lst[0] ==0:
    # lst.remove(lst[j])baesu_lst.append(lst[j])
    cnt+=1ifcnt==k:
    print(baesu_lst[-1])
    breakifcnt==k:
    breaklst= [xforxinlstifxnotinbaesu_lst]

    느낀점

    첫번째 시도에서,

    importsysinput=sys.stdin.readlinen, k=map(int, input().split())
    cnt=0# 순서 카운트# 2부터 n 까지lst= [iforiinrange(2, n+1)]
    whilelen(lst) !=0:
    # 가장 작은 수 : pmin_num=lst[0]
    baesu_lst= []
    forjinrange(len(lst)): # 2~7iflst[j] %lst[0] ==0:
    # lst.remove(lst[j])baesu_lst.append(lst[j])
    cnt+=1ifcnt==k:
    print(baesu_lst[-1])
    breaklst= [xforxinlstifxnotinbaesu_lst]

    if문을 for문 밖으로 빼서, cnt가 k와 같을때 멈춰야 하는데 그러지 못하고 계속 반복문을 돌았다.

    따라서 if문을 for문 안으로 넣어서 for문의 종료조건을 만족시켰으며 if문을 밖으로 빼서 while 문의 종료조건을 만족시켰다.

    리스트를 구할 때 위처럼 리스트 컴프리헨션을 이용하니 코드가 짧아진 데서 오는 안정감과 가독성이 있는거 같다.(유용하게 쓰자)

    사실 첫번째 코드는 test case는 모두 통과해서 정답인줄 알았지만, 제출 시 17%에서 오답이었고, 반례를 찾는 실력까지는 도달을 못해서 chatGPT가 10 3 가 반례임을 제시해서 이를 이용해서 완전한 코드가 되었다.

    반례 찾는 연습 해봐야지(어떻게?)

    반례 찾기

    (https://velog.io/@juyeonma9/%EB%B0%B1%EC%A4%80-%EC%9E%90%EC%A3%BC%ED%8B%80%EB%A6%AC%EB%8A%94%EC%9A%94%EC%9D%B8)

    • 가장 중요한 것은 직접 데이터를 만들어서 넣어 보는 것입니다.https://www.acmicpc.net/problem/14405 를 예로 들어 봅시다. 그러면 이런 입력들을 넣어 볼 수 있습니다.
      • pi 하나만 넣으면? ka? chu? 한 글자만 넣으면? p? k? c? i? a? r?
      • pika는 YES가 나와야 합니다. 이걸 조금 변형하면? pik? pia? pka? piak? pkia? ipka? kipa? pikaa? pikka? piika? ppika?
      • kapi도 YES가 나와야 합니다. 이걸 조금 변형하면? kap? kai? api? kaip? kpai? kapii? kaapi?
      • 주어진 예제를 조금 변형하면? pikap? pikpi? pipikach? pipikaphu?
      • 그냥 정말로 아무거나 넣으면? abcd? pipichukachuka? pichaku? ppap? pikach?
    • 입력으로 1 이상 1,000,000 이하의 정수 N이 주어진다면 N=1, N=2 등의 최소 케이스가 잘 나오는지 확인하는 것이 좋습니다. 이런 입력이 특이 케이스가 되는 문제들이 종종 있고, 굳이 특이 케이스가 아니더라도 우리의 코드가 최소 케이스에서 틀릴 가능성은 얼마든지 있습니다. 위에서 언급한 "피카츄" 문제의 경우 p, k 등의 한 글자짜리 입력이 여기에 해당되겠죠.
    • N=1,000,000 같은 최대 케이스를 넣었을 때 주어진 시간 제한 안에 답이 나오는지도 확인해 볼 수 있습니다. 답이 맞는지 확인하는 건 어떨까요? 문제에 따라 답을 손으로 알아내기 힘들 수도 있는데, 적어도 말이 되는 값은 나와야겠죠? 출력이 무조건 0 이상일 수밖에 없는 문제에서 음수가 나오면 뭔가 잘못되었다는 뜻입니다.

    Metadata

    Metadata

    Assignees

    Labels

    documentationImprovements or additions to documentation

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
      Skip to content

      BOJ 2960 에라토스테네스의 체 풀이 #9

      Description

      @allzeroyou

      문제 분석

      첫 번째 단계(문제 요약 및 조건 파악)

      에라토스테네스의 체: n보다 작거나 같은 모든 소수를 찾는 알고리즘.

      1. 2부터 n까지 모든 정수를 적는다
      2. 아직 지우지 않은 수 중 가장 작은 수 찾기. 이걸 p라고 하고, 이 수는 소수임.
      3. p를 지우고, 아직 지우지 않은 p의 배수를 크기 순서대로 지운다
      4. 아직 모든 수를 지우지 않았다면 다시 2번 단계로 간다.

      n, k가 주어졌을 때 k번째 지우는 수를 구하는 프로그램 작성.

      입력

      • n, k가 주어짐(1 ≤ K < N, max(1, K) < N ≤ 1000)

      출력

      • k번째 지워진 수를 출력.

      두 번째 단계 (문제 핵심 파악)

      1. 2~n까지 정수가 담긴 리스트를 만든다.
      2. 가장 작은 수를 p라고 할때, p는 소수임.
      3. p를 리스트에서 삭제하고, 리스트에 남아있는 p의 배수를 크기순으로 지운다.
      4. 이때, p가 1st, p의 배수 중 첫번째 요소가 2nd, p의 배수 중 2번째 요소가 3rd 순이다.
      5. 이때 리스트가 비어있지 않다면(while 리스트) 다시 2번으로 가서 단계를 지속한다.

      코드 작성

      importsysinput=sys.stdin.readlinen, k=map(int, input().split())
      cnt=0# 순서 카운트# 2부터 n 까지lst= [iforiinrange(2, n+1)]
      whilelen(lst) !=0:
      # 가장 작은 수 : pmin_num=lst[0]
      baesu_lst= []
      forjinrange(len(lst)): # 2~7iflst[j] %lst[0] ==0:
      # lst.remove(lst[j])baesu_lst.append(lst[j])
      cnt+=1ifcnt==k:
      print(baesu_lst[-1])
      breakifcnt==k:
      breaklst= [xforxinlstifxnotinbaesu_lst]

      느낀점

      첫번째 시도에서,

      importsysinput=sys.stdin.readlinen, k=map(int, input().split())
      cnt=0# 순서 카운트# 2부터 n 까지lst= [iforiinrange(2, n+1)]
      whilelen(lst) !=0:
      # 가장 작은 수 : pmin_num=lst[0]
      baesu_lst= []
      forjinrange(len(lst)): # 2~7iflst[j] %lst[0] ==0:
      # lst.remove(lst[j])baesu_lst.append(lst[j])
      cnt+=1ifcnt==k:
      print(baesu_lst[-1])
      breaklst= [xforxinlstifxnotinbaesu_lst]

      if문을 for문 밖으로 빼서, cnt가 k와 같을때 멈춰야 하는데 그러지 못하고 계속 반복문을 돌았다.

      따라서 if문을 for문 안으로 넣어서 for문의 종료조건을 만족시켰으며 if문을 밖으로 빼서 while 문의 종료조건을 만족시켰다.

      리스트를 구할 때 위처럼 리스트 컴프리헨션을 이용하니 코드가 짧아진 데서 오는 안정감과 가독성이 있는거 같다.(유용하게 쓰자)

      사실 첫번째 코드는 test case는 모두 통과해서 정답인줄 알았지만, 제출 시 17%에서 오답이었고, 반례를 찾는 실력까지는 도달을 못해서 chatGPT가 10 3 가 반례임을 제시해서 이를 이용해서 완전한 코드가 되었다.

      반례 찾는 연습 해봐야지(어떻게?)

      반례 찾기

      (https://velog.io/@juyeonma9/%EB%B0%B1%EC%A4%80-%EC%9E%90%EC%A3%BC%ED%8B%80%EB%A6%AC%EB%8A%94%EC%9A%94%EC%9D%B8)

      • 가장 중요한 것은 직접 데이터를 만들어서 넣어 보는 것입니다.https://www.acmicpc.net/problem/14405 를 예로 들어 봅시다. 그러면 이런 입력들을 넣어 볼 수 있습니다.
        • pi 하나만 넣으면? ka? chu? 한 글자만 넣으면? p? k? c? i? a? r?
        • pika는 YES가 나와야 합니다. 이걸 조금 변형하면? pik? pia? pka? piak? pkia? ipka? kipa? pikaa? pikka? piika? ppika?
        • kapi도 YES가 나와야 합니다. 이걸 조금 변형하면? kap? kai? api? kaip? kpai? kapii? kaapi?
        • 주어진 예제를 조금 변형하면? pikap? pikpi? pipikach? pipikaphu?
        • 그냥 정말로 아무거나 넣으면? abcd? pipichukachuka? pichaku? ppap? pikach?
      • 입력으로 1 이상 1,000,000 이하의 정수 N이 주어진다면 N=1, N=2 등의 최소 케이스가 잘 나오는지 확인하는 것이 좋습니다. 이런 입력이 특이 케이스가 되는 문제들이 종종 있고, 굳이 특이 케이스가 아니더라도 우리의 코드가 최소 케이스에서 틀릴 가능성은 얼마든지 있습니다. 위에서 언급한 "피카츄" 문제의 경우 p, k 등의 한 글자짜리 입력이 여기에 해당되겠죠.
      • N=1,000,000 같은 최대 케이스를 넣었을 때 주어진 시간 제한 안에 답이 나오는지도 확인해 볼 수 있습니다. 답이 맞는지 확인하는 건 어떨까요? 문제에 따라 답을 손으로 알아내기 힘들 수도 있는데, 적어도 말이 되는 값은 나와야겠죠? 출력이 무조건 0 이상일 수밖에 없는 문제에서 음수가 나오면 뭔가 잘못되었다는 뜻입니다.

      Metadata

      Metadata

      Assignees

      Labels

      documentationImprovements or additions to documentation

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

        , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
        Skip to content

        BOJ 2960 에라토스테네스의 체 풀이 #9

        Description

        @allzeroyou

        문제 분석

        첫 번째 단계(문제 요약 및 조건 파악)

        에라토스테네스의 체: n보다 작거나 같은 모든 소수를 찾는 알고리즘.

        1. 2부터 n까지 모든 정수를 적는다
        2. 아직 지우지 않은 수 중 가장 작은 수 찾기. 이걸 p라고 하고, 이 수는 소수임.
        3. p를 지우고, 아직 지우지 않은 p의 배수를 크기 순서대로 지운다
        4. 아직 모든 수를 지우지 않았다면 다시 2번 단계로 간다.

        n, k가 주어졌을 때 k번째 지우는 수를 구하는 프로그램 작성.

        입력

        • n, k가 주어짐(1 ≤ K < N, max(1, K) < N ≤ 1000)

        출력

        • k번째 지워진 수를 출력.

        두 번째 단계 (문제 핵심 파악)

        1. 2~n까지 정수가 담긴 리스트를 만든다.
        2. 가장 작은 수를 p라고 할때, p는 소수임.
        3. p를 리스트에서 삭제하고, 리스트에 남아있는 p의 배수를 크기순으로 지운다.
        4. 이때, p가 1st, p의 배수 중 첫번째 요소가 2nd, p의 배수 중 2번째 요소가 3rd 순이다.
        5. 이때 리스트가 비어있지 않다면(while 리스트) 다시 2번으로 가서 단계를 지속한다.

        코드 작성

        importsysinput=sys.stdin.readlinen, k=map(int, input().split())
        cnt=0# 순서 카운트# 2부터 n 까지lst= [iforiinrange(2, n+1)]
        whilelen(lst) !=0:
        # 가장 작은 수 : pmin_num=lst[0]
        baesu_lst= []
        forjinrange(len(lst)): # 2~7iflst[j] %lst[0] ==0:
        # lst.remove(lst[j])baesu_lst.append(lst[j])
        cnt+=1ifcnt==k:
        print(baesu_lst[-1])
        breakifcnt==k:
        breaklst= [xforxinlstifxnotinbaesu_lst]

        느낀점

        첫번째 시도에서,

        importsysinput=sys.stdin.readlinen, k=map(int, input().split())
        cnt=0# 순서 카운트# 2부터 n 까지lst= [iforiinrange(2, n+1)]
        whilelen(lst) !=0:
        # 가장 작은 수 : pmin_num=lst[0]
        baesu_lst= []
        forjinrange(len(lst)): # 2~7iflst[j] %lst[0] ==0:
        # lst.remove(lst[j])baesu_lst.append(lst[j])
        cnt+=1ifcnt==k:
        print(baesu_lst[-1])
        breaklst= [xforxinlstifxnotinbaesu_lst]

        if문을 for문 밖으로 빼서, cnt가 k와 같을때 멈춰야 하는데 그러지 못하고 계속 반복문을 돌았다.

        따라서 if문을 for문 안으로 넣어서 for문의 종료조건을 만족시켰으며 if문을 밖으로 빼서 while 문의 종료조건을 만족시켰다.

        리스트를 구할 때 위처럼 리스트 컴프리헨션을 이용하니 코드가 짧아진 데서 오는 안정감과 가독성이 있는거 같다.(유용하게 쓰자)

        사실 첫번째 코드는 test case는 모두 통과해서 정답인줄 알았지만, 제출 시 17%에서 오답이었고, 반례를 찾는 실력까지는 도달을 못해서 chatGPT가 10 3 가 반례임을 제시해서 이를 이용해서 완전한 코드가 되었다.

        반례 찾는 연습 해봐야지(어떻게?)

        반례 찾기

        (https://velog.io/@juyeonma9/%EB%B0%B1%EC%A4%80-%EC%9E%90%EC%A3%BC%ED%8B%80%EB%A6%AC%EB%8A%94%EC%9A%94%EC%9D%B8)

        • 가장 중요한 것은 직접 데이터를 만들어서 넣어 보는 것입니다.https://www.acmicpc.net/problem/14405 를 예로 들어 봅시다. 그러면 이런 입력들을 넣어 볼 수 있습니다.
          • pi 하나만 넣으면? ka? chu? 한 글자만 넣으면? p? k? c? i? a? r?
          • pika는 YES가 나와야 합니다. 이걸 조금 변형하면? pik? pia? pka? piak? pkia? ipka? kipa? pikaa? pikka? piika? ppika?
          • kapi도 YES가 나와야 합니다. 이걸 조금 변형하면? kap? kai? api? kaip? kpai? kapii? kaapi?
          • 주어진 예제를 조금 변형하면? pikap? pikpi? pipikach? pipikaphu?
          • 그냥 정말로 아무거나 넣으면? abcd? pipichukachuka? pichaku? ppap? pikach?
        • 입력으로 1 이상 1,000,000 이하의 정수 N이 주어진다면 N=1, N=2 등의 최소 케이스가 잘 나오는지 확인하는 것이 좋습니다. 이런 입력이 특이 케이스가 되는 문제들이 종종 있고, 굳이 특이 케이스가 아니더라도 우리의 코드가 최소 케이스에서 틀릴 가능성은 얼마든지 있습니다. 위에서 언급한 "피카츄" 문제의 경우 p, k 등의 한 글자짜리 입력이 여기에 해당되겠죠.
        • N=1,000,000 같은 최대 케이스를 넣었을 때 주어진 시간 제한 안에 답이 나오는지도 확인해 볼 수 있습니다. 답이 맞는지 확인하는 건 어떨까요? 문제에 따라 답을 손으로 알아내기 힘들 수도 있는데, 적어도 말이 되는 값은 나와야겠죠? 출력이 무조건 0 이상일 수밖에 없는 문제에서 음수가 나오면 뭔가 잘못되었다는 뜻입니다.

        Metadata

        Metadata

        Assignees

        Labels

        documentationImprovements or additions to documentation

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
          Skip to content

          BOJ 2960 에라토스테네스의 체 풀이 #9

          Description

          @allzeroyou

          문제 분석

          첫 번째 단계(문제 요약 및 조건 파악)

          에라토스테네스의 체: n보다 작거나 같은 모든 소수를 찾는 알고리즘.

          1. 2부터 n까지 모든 정수를 적는다
          2. 아직 지우지 않은 수 중 가장 작은 수 찾기. 이걸 p라고 하고, 이 수는 소수임.
          3. p를 지우고, 아직 지우지 않은 p의 배수를 크기 순서대로 지운다
          4. 아직 모든 수를 지우지 않았다면 다시 2번 단계로 간다.

          n, k가 주어졌을 때 k번째 지우는 수를 구하는 프로그램 작성.

          입력

          • n, k가 주어짐(1 ≤ K < N, max(1, K) < N ≤ 1000)

          출력

          • k번째 지워진 수를 출력.

          두 번째 단계 (문제 핵심 파악)

          1. 2~n까지 정수가 담긴 리스트를 만든다.
          2. 가장 작은 수를 p라고 할때, p는 소수임.
          3. p를 리스트에서 삭제하고, 리스트에 남아있는 p의 배수를 크기순으로 지운다.
          4. 이때, p가 1st, p의 배수 중 첫번째 요소가 2nd, p의 배수 중 2번째 요소가 3rd 순이다.
          5. 이때 리스트가 비어있지 않다면(while 리스트) 다시 2번으로 가서 단계를 지속한다.

          코드 작성

          importsysinput=sys.stdin.readlinen, k=map(int, input().split())
          cnt=0# 순서 카운트# 2부터 n 까지lst= [iforiinrange(2, n+1)]
          whilelen(lst) !=0:
          # 가장 작은 수 : pmin_num=lst[0]
          baesu_lst= []
          forjinrange(len(lst)): # 2~7iflst[j] %lst[0] ==0:
          # lst.remove(lst[j])baesu_lst.append(lst[j])
          cnt+=1ifcnt==k:
          print(baesu_lst[-1])
          breakifcnt==k:
          breaklst= [xforxinlstifxnotinbaesu_lst]

          느낀점

          첫번째 시도에서,

          importsysinput=sys.stdin.readlinen, k=map(int, input().split())
          cnt=0# 순서 카운트# 2부터 n 까지lst= [iforiinrange(2, n+1)]
          whilelen(lst) !=0:
          # 가장 작은 수 : pmin_num=lst[0]
          baesu_lst= []
          forjinrange(len(lst)): # 2~7iflst[j] %lst[0] ==0:
          # lst.remove(lst[j])baesu_lst.append(lst[j])
          cnt+=1ifcnt==k:
          print(baesu_lst[-1])
          breaklst= [xforxinlstifxnotinbaesu_lst]

          if문을 for문 밖으로 빼서, cnt가 k와 같을때 멈춰야 하는데 그러지 못하고 계속 반복문을 돌았다.

          따라서 if문을 for문 안으로 넣어서 for문의 종료조건을 만족시켰으며 if문을 밖으로 빼서 while 문의 종료조건을 만족시켰다.

          리스트를 구할 때 위처럼 리스트 컴프리헨션을 이용하니 코드가 짧아진 데서 오는 안정감과 가독성이 있는거 같다.(유용하게 쓰자)

          사실 첫번째 코드는 test case는 모두 통과해서 정답인줄 알았지만, 제출 시 17%에서 오답이었고, 반례를 찾는 실력까지는 도달을 못해서 chatGPT가 10 3 가 반례임을 제시해서 이를 이용해서 완전한 코드가 되었다.

          반례 찾는 연습 해봐야지(어떻게?)

          반례 찾기

          (https://velog.io/@juyeonma9/%EB%B0%B1%EC%A4%80-%EC%9E%90%EC%A3%BC%ED%8B%80%EB%A6%AC%EB%8A%94%EC%9A%94%EC%9D%B8)

          • 가장 중요한 것은 직접 데이터를 만들어서 넣어 보는 것입니다.https://www.acmicpc.net/problem/14405 를 예로 들어 봅시다. 그러면 이런 입력들을 넣어 볼 수 있습니다.
            • pi 하나만 넣으면? ka? chu? 한 글자만 넣으면? p? k? c? i? a? r?
            • pika는 YES가 나와야 합니다. 이걸 조금 변형하면? pik? pia? pka? piak? pkia? ipka? kipa? pikaa? pikka? piika? ppika?
            • kapi도 YES가 나와야 합니다. 이걸 조금 변형하면? kap? kai? api? kaip? kpai? kapii? kaapi?
            • 주어진 예제를 조금 변형하면? pikap? pikpi? pipikach? pipikaphu?
            • 그냥 정말로 아무거나 넣으면? abcd? pipichukachuka? pichaku? ppap? pikach?
          • 입력으로 1 이상 1,000,000 이하의 정수 N이 주어진다면 N=1, N=2 등의 최소 케이스가 잘 나오는지 확인하는 것이 좋습니다. 이런 입력이 특이 케이스가 되는 문제들이 종종 있고, 굳이 특이 케이스가 아니더라도 우리의 코드가 최소 케이스에서 틀릴 가능성은 얼마든지 있습니다. 위에서 언급한 "피카츄" 문제의 경우 p, k 등의 한 글자짜리 입력이 여기에 해당되겠죠.
          • N=1,000,000 같은 최대 케이스를 넣었을 때 주어진 시간 제한 안에 답이 나오는지도 확인해 볼 수 있습니다. 답이 맞는지 확인하는 건 어떨까요? 문제에 따라 답을 손으로 알아내기 힘들 수도 있는데, 적어도 말이 되는 값은 나와야겠죠? 출력이 무조건 0 이상일 수밖에 없는 문제에서 음수가 나오면 뭔가 잘못되었다는 뜻입니다.

          Metadata

          Metadata

          Assignees

          Labels

          documentationImprovements or additions to documentation

          Projects

          No projects

            Milestone

            No milestone

            Relationships

            None yet

            Development

            No branches or pull requests

            Issue actions

            , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
            Skip to content

            BOJ 2960 에라토스테네스의 체 풀이 #9

            Description

            @allzeroyou

            문제 분석

            첫 번째 단계(문제 요약 및 조건 파악)

            에라토스테네스의 체: n보다 작거나 같은 모든 소수를 찾는 알고리즘.

            1. 2부터 n까지 모든 정수를 적는다
            2. 아직 지우지 않은 수 중 가장 작은 수 찾기. 이걸 p라고 하고, 이 수는 소수임.
            3. p를 지우고, 아직 지우지 않은 p의 배수를 크기 순서대로 지운다
            4. 아직 모든 수를 지우지 않았다면 다시 2번 단계로 간다.

            n, k가 주어졌을 때 k번째 지우는 수를 구하는 프로그램 작성.

            입력

            • n, k가 주어짐(1 ≤ K < N, max(1, K) < N ≤ 1000)

            출력

            • k번째 지워진 수를 출력.

            두 번째 단계 (문제 핵심 파악)

            1. 2~n까지 정수가 담긴 리스트를 만든다.
            2. 가장 작은 수를 p라고 할때, p는 소수임.
            3. p를 리스트에서 삭제하고, 리스트에 남아있는 p의 배수를 크기순으로 지운다.
            4. 이때, p가 1st, p의 배수 중 첫번째 요소가 2nd, p의 배수 중 2번째 요소가 3rd 순이다.
            5. 이때 리스트가 비어있지 않다면(while 리스트) 다시 2번으로 가서 단계를 지속한다.

            코드 작성

            importsysinput=sys.stdin.readlinen, k=map(int, input().split())
            cnt=0# 순서 카운트# 2부터 n 까지lst= [iforiinrange(2, n+1)]
            whilelen(lst) !=0:
            # 가장 작은 수 : pmin_num=lst[0]
            baesu_lst= []
            forjinrange(len(lst)): # 2~7iflst[j] %lst[0] ==0:
            # lst.remove(lst[j])baesu_lst.append(lst[j])
            cnt+=1ifcnt==k:
            print(baesu_lst[-1])
            breakifcnt==k:
            breaklst= [xforxinlstifxnotinbaesu_lst]

            느낀점

            첫번째 시도에서,

            importsysinput=sys.stdin.readlinen, k=map(int, input().split())
            cnt=0# 순서 카운트# 2부터 n 까지lst= [iforiinrange(2, n+1)]
            whilelen(lst) !=0:
            # 가장 작은 수 : pmin_num=lst[0]
            baesu_lst= []
            forjinrange(len(lst)): # 2~7iflst[j] %lst[0] ==0:
            # lst.remove(lst[j])baesu_lst.append(lst[j])
            cnt+=1ifcnt==k:
            print(baesu_lst[-1])
            breaklst= [xforxinlstifxnotinbaesu_lst]

            if문을 for문 밖으로 빼서, cnt가 k와 같을때 멈춰야 하는데 그러지 못하고 계속 반복문을 돌았다.

            따라서 if문을 for문 안으로 넣어서 for문의 종료조건을 만족시켰으며 if문을 밖으로 빼서 while 문의 종료조건을 만족시켰다.

            리스트를 구할 때 위처럼 리스트 컴프리헨션을 이용하니 코드가 짧아진 데서 오는 안정감과 가독성이 있는거 같다.(유용하게 쓰자)

            사실 첫번째 코드는 test case는 모두 통과해서 정답인줄 알았지만, 제출 시 17%에서 오답이었고, 반례를 찾는 실력까지는 도달을 못해서 chatGPT가 10 3 가 반례임을 제시해서 이를 이용해서 완전한 코드가 되었다.

            반례 찾는 연습 해봐야지(어떻게?)

            반례 찾기

            (https://velog.io/@juyeonma9/%EB%B0%B1%EC%A4%80-%EC%9E%90%EC%A3%BC%ED%8B%80%EB%A6%AC%EB%8A%94%EC%9A%94%EC%9D%B8)

            • 가장 중요한 것은 직접 데이터를 만들어서 넣어 보는 것입니다.https://www.acmicpc.net/problem/14405 를 예로 들어 봅시다. 그러면 이런 입력들을 넣어 볼 수 있습니다.
              • pi 하나만 넣으면? ka? chu? 한 글자만 넣으면? p? k? c? i? a? r?
              • pika는 YES가 나와야 합니다. 이걸 조금 변형하면? pik? pia? pka? piak? pkia? ipka? kipa? pikaa? pikka? piika? ppika?
              • kapi도 YES가 나와야 합니다. 이걸 조금 변형하면? kap? kai? api? kaip? kpai? kapii? kaapi?
              • 주어진 예제를 조금 변형하면? pikap? pikpi? pipikach? pipikaphu?
              • 그냥 정말로 아무거나 넣으면? abcd? pipichukachuka? pichaku? ppap? pikach?
            • 입력으로 1 이상 1,000,000 이하의 정수 N이 주어진다면 N=1, N=2 등의 최소 케이스가 잘 나오는지 확인하는 것이 좋습니다. 이런 입력이 특이 케이스가 되는 문제들이 종종 있고, 굳이 특이 케이스가 아니더라도 우리의 코드가 최소 케이스에서 틀릴 가능성은 얼마든지 있습니다. 위에서 언급한 "피카츄" 문제의 경우 p, k 등의 한 글자짜리 입력이 여기에 해당되겠죠.
            • N=1,000,000 같은 최대 케이스를 넣었을 때 주어진 시간 제한 안에 답이 나오는지도 확인해 볼 수 있습니다. 답이 맞는지 확인하는 건 어떨까요? 문제에 따라 답을 손으로 알아내기 힘들 수도 있는데, 적어도 말이 되는 값은 나와야겠죠? 출력이 무조건 0 이상일 수밖에 없는 문제에서 음수가 나오면 뭔가 잘못되었다는 뜻입니다.

            Metadata

            Metadata

            Assignees

            Labels

            documentationImprovements or additions to documentation

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
              Skip to content

              BOJ 2960 에라토스테네스의 체 풀이 #9

              Description

              @allzeroyou

              문제 분석

              첫 번째 단계(문제 요약 및 조건 파악)

              에라토스테네스의 체: n보다 작거나 같은 모든 소수를 찾는 알고리즘.

              1. 2부터 n까지 모든 정수를 적는다
              2. 아직 지우지 않은 수 중 가장 작은 수 찾기. 이걸 p라고 하고, 이 수는 소수임.
              3. p를 지우고, 아직 지우지 않은 p의 배수를 크기 순서대로 지운다
              4. 아직 모든 수를 지우지 않았다면 다시 2번 단계로 간다.

              n, k가 주어졌을 때 k번째 지우는 수를 구하는 프로그램 작성.

              입력

              • n, k가 주어짐(1 ≤ K < N, max(1, K) < N ≤ 1000)

              출력

              • k번째 지워진 수를 출력.

              두 번째 단계 (문제 핵심 파악)

              1. 2~n까지 정수가 담긴 리스트를 만든다.
              2. 가장 작은 수를 p라고 할때, p는 소수임.
              3. p를 리스트에서 삭제하고, 리스트에 남아있는 p의 배수를 크기순으로 지운다.
              4. 이때, p가 1st, p의 배수 중 첫번째 요소가 2nd, p의 배수 중 2번째 요소가 3rd 순이다.
              5. 이때 리스트가 비어있지 않다면(while 리스트) 다시 2번으로 가서 단계를 지속한다.

              코드 작성

              importsysinput=sys.stdin.readlinen, k=map(int, input().split())
              cnt=0# 순서 카운트# 2부터 n 까지lst= [iforiinrange(2, n+1)]
              whilelen(lst) !=0:
              # 가장 작은 수 : pmin_num=lst[0]
              baesu_lst= []
              forjinrange(len(lst)): # 2~7iflst[j] %lst[0] ==0:
              # lst.remove(lst[j])baesu_lst.append(lst[j])
              cnt+=1ifcnt==k:
              print(baesu_lst[-1])
              breakifcnt==k:
              breaklst= [xforxinlstifxnotinbaesu_lst]

              느낀점

              첫번째 시도에서,

              importsysinput=sys.stdin.readlinen, k=map(int, input().split())
              cnt=0# 순서 카운트# 2부터 n 까지lst= [iforiinrange(2, n+1)]
              whilelen(lst) !=0:
              # 가장 작은 수 : pmin_num=lst[0]
              baesu_lst= []
              forjinrange(len(lst)): # 2~7iflst[j] %lst[0] ==0:
              # lst.remove(lst[j])baesu_lst.append(lst[j])
              cnt+=1ifcnt==k:
              print(baesu_lst[-1])
              breaklst= [xforxinlstifxnotinbaesu_lst]

              if문을 for문 밖으로 빼서, cnt가 k와 같을때 멈춰야 하는데 그러지 못하고 계속 반복문을 돌았다.

              따라서 if문을 for문 안으로 넣어서 for문의 종료조건을 만족시켰으며 if문을 밖으로 빼서 while 문의 종료조건을 만족시켰다.

              리스트를 구할 때 위처럼 리스트 컴프리헨션을 이용하니 코드가 짧아진 데서 오는 안정감과 가독성이 있는거 같다.(유용하게 쓰자)

              사실 첫번째 코드는 test case는 모두 통과해서 정답인줄 알았지만, 제출 시 17%에서 오답이었고, 반례를 찾는 실력까지는 도달을 못해서 chatGPT가 10 3 가 반례임을 제시해서 이를 이용해서 완전한 코드가 되었다.

              반례 찾는 연습 해봐야지(어떻게?)

              반례 찾기

              (https://velog.io/@juyeonma9/%EB%B0%B1%EC%A4%80-%EC%9E%90%EC%A3%BC%ED%8B%80%EB%A6%AC%EB%8A%94%EC%9A%94%EC%9D%B8)

              • 가장 중요한 것은 직접 데이터를 만들어서 넣어 보는 것입니다.https://www.acmicpc.net/problem/14405 를 예로 들어 봅시다. 그러면 이런 입력들을 넣어 볼 수 있습니다.
                • pi 하나만 넣으면? ka? chu? 한 글자만 넣으면? p? k? c? i? a? r?
                • pika는 YES가 나와야 합니다. 이걸 조금 변형하면? pik? pia? pka? piak? pkia? ipka? kipa? pikaa? pikka? piika? ppika?
                • kapi도 YES가 나와야 합니다. 이걸 조금 변형하면? kap? kai? api? kaip? kpai? kapii? kaapi?
                • 주어진 예제를 조금 변형하면? pikap? pikpi? pipikach? pipikaphu?
                • 그냥 정말로 아무거나 넣으면? abcd? pipichukachuka? pichaku? ppap? pikach?
              • 입력으로 1 이상 1,000,000 이하의 정수 N이 주어진다면 N=1, N=2 등의 최소 케이스가 잘 나오는지 확인하는 것이 좋습니다. 이런 입력이 특이 케이스가 되는 문제들이 종종 있고, 굳이 특이 케이스가 아니더라도 우리의 코드가 최소 케이스에서 틀릴 가능성은 얼마든지 있습니다. 위에서 언급한 "피카츄" 문제의 경우 p, k 등의 한 글자짜리 입력이 여기에 해당되겠죠.
              • N=1,000,000 같은 최대 케이스를 넣었을 때 주어진 시간 제한 안에 답이 나오는지도 확인해 볼 수 있습니다. 답이 맞는지 확인하는 건 어떨까요? 문제에 따라 답을 손으로 알아내기 힘들 수도 있는데, 적어도 말이 되는 값은 나와야겠죠? 출력이 무조건 0 이상일 수밖에 없는 문제에서 음수가 나오면 뭔가 잘못되었다는 뜻입니다.

              Metadata

              Metadata

              Assignees

              Labels

              documentationImprovements or additions to documentation

              Projects

              No projects

                Milestone

                No milestone

                Relationships

                None yet

                Development

                No branches or pull requests

                Issue actions

                , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
                Skip to content

                BOJ 2960 에라토스테네스의 체 풀이 #9

                Description

                @allzeroyou

                문제 분석

                첫 번째 단계(문제 요약 및 조건 파악)

                에라토스테네스의 체: n보다 작거나 같은 모든 소수를 찾는 알고리즘.

                1. 2부터 n까지 모든 정수를 적는다
                2. 아직 지우지 않은 수 중 가장 작은 수 찾기. 이걸 p라고 하고, 이 수는 소수임.
                3. p를 지우고, 아직 지우지 않은 p의 배수를 크기 순서대로 지운다
                4. 아직 모든 수를 지우지 않았다면 다시 2번 단계로 간다.

                n, k가 주어졌을 때 k번째 지우는 수를 구하는 프로그램 작성.

                입력

                • n, k가 주어짐(1 ≤ K < N, max(1, K) < N ≤ 1000)

                출력

                • k번째 지워진 수를 출력.

                두 번째 단계 (문제 핵심 파악)

                1. 2~n까지 정수가 담긴 리스트를 만든다.
                2. 가장 작은 수를 p라고 할때, p는 소수임.
                3. p를 리스트에서 삭제하고, 리스트에 남아있는 p의 배수를 크기순으로 지운다.
                4. 이때, p가 1st, p의 배수 중 첫번째 요소가 2nd, p의 배수 중 2번째 요소가 3rd 순이다.
                5. 이때 리스트가 비어있지 않다면(while 리스트) 다시 2번으로 가서 단계를 지속한다.

                코드 작성

                importsysinput=sys.stdin.readlinen, k=map(int, input().split())
                cnt=0# 순서 카운트# 2부터 n 까지lst= [iforiinrange(2, n+1)]
                whilelen(lst) !=0:
                # 가장 작은 수 : pmin_num=lst[0]
                baesu_lst= []
                forjinrange(len(lst)): # 2~7iflst[j] %lst[0] ==0:
                # lst.remove(lst[j])baesu_lst.append(lst[j])
                cnt+=1ifcnt==k:
                print(baesu_lst[-1])
                breakifcnt==k:
                breaklst= [xforxinlstifxnotinbaesu_lst]

                느낀점

                첫번째 시도에서,

                importsysinput=sys.stdin.readlinen, k=map(int, input().split())
                cnt=0# 순서 카운트# 2부터 n 까지lst= [iforiinrange(2, n+1)]
                whilelen(lst) !=0:
                # 가장 작은 수 : pmin_num=lst[0]
                baesu_lst= []
                forjinrange(len(lst)): # 2~7iflst[j] %lst[0] ==0:
                # lst.remove(lst[j])baesu_lst.append(lst[j])
                cnt+=1ifcnt==k:
                print(baesu_lst[-1])
                breaklst= [xforxinlstifxnotinbaesu_lst]

                if문을 for문 밖으로 빼서, cnt가 k와 같을때 멈춰야 하는데 그러지 못하고 계속 반복문을 돌았다.

                따라서 if문을 for문 안으로 넣어서 for문의 종료조건을 만족시켰으며 if문을 밖으로 빼서 while 문의 종료조건을 만족시켰다.

                리스트를 구할 때 위처럼 리스트 컴프리헨션을 이용하니 코드가 짧아진 데서 오는 안정감과 가독성이 있는거 같다.(유용하게 쓰자)

                사실 첫번째 코드는 test case는 모두 통과해서 정답인줄 알았지만, 제출 시 17%에서 오답이었고, 반례를 찾는 실력까지는 도달을 못해서 chatGPT가 10 3 가 반례임을 제시해서 이를 이용해서 완전한 코드가 되었다.

                반례 찾는 연습 해봐야지(어떻게?)

                반례 찾기

                (https://velog.io/@juyeonma9/%EB%B0%B1%EC%A4%80-%EC%9E%90%EC%A3%BC%ED%8B%80%EB%A6%AC%EB%8A%94%EC%9A%94%EC%9D%B8)

                • 가장 중요한 것은 직접 데이터를 만들어서 넣어 보는 것입니다.https://www.acmicpc.net/problem/14405 를 예로 들어 봅시다. 그러면 이런 입력들을 넣어 볼 수 있습니다.
                  • pi 하나만 넣으면? ka? chu? 한 글자만 넣으면? p? k? c? i? a? r?
                  • pika는 YES가 나와야 합니다. 이걸 조금 변형하면? pik? pia? pka? piak? pkia? ipka? kipa? pikaa? pikka? piika? ppika?
                  • kapi도 YES가 나와야 합니다. 이걸 조금 변형하면? kap? kai? api? kaip? kpai? kapii? kaapi?
                  • 주어진 예제를 조금 변형하면? pikap? pikpi? pipikach? pipikaphu?
                  • 그냥 정말로 아무거나 넣으면? abcd? pipichukachuka? pichaku? ppap? pikach?
                • 입력으로 1 이상 1,000,000 이하의 정수 N이 주어진다면 N=1, N=2 등의 최소 케이스가 잘 나오는지 확인하는 것이 좋습니다. 이런 입력이 특이 케이스가 되는 문제들이 종종 있고, 굳이 특이 케이스가 아니더라도 우리의 코드가 최소 케이스에서 틀릴 가능성은 얼마든지 있습니다. 위에서 언급한 "피카츄" 문제의 경우 p, k 등의 한 글자짜리 입력이 여기에 해당되겠죠.
                • N=1,000,000 같은 최대 케이스를 넣었을 때 주어진 시간 제한 안에 답이 나오는지도 확인해 볼 수 있습니다. 답이 맞는지 확인하는 건 어떨까요? 문제에 따라 답을 손으로 알아내기 힘들 수도 있는데, 적어도 말이 되는 값은 나와야겠죠? 출력이 무조건 0 이상일 수밖에 없는 문제에서 음수가 나오면 뭔가 잘못되었다는 뜻입니다.

                Metadata

                Metadata

                Assignees

                Labels

                documentationImprovements or additions to documentation

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions