study gomi

[백준/baekjoon] 13909번 창문 닫기 (파이썬) 본문

Practice/Baekjoon

[백준/baekjoon] 13909번 창문 닫기 (파이썬)

공부하곰 2024. 1. 11. 04:16
728x90
반응형

내 제출

- 첫 제출은 틀렸었다(복잡도 n^2인 중첩 for문 쓴 첫 제출 ↓)

더보기
# 창문의 개수와 사람의 수 n이 주어진다.
n = int(input())

# 처음에 모든 창문은 닫혀 있다.
window = [False] * n

for num in range(1, n+1):
    for i in range(num, n, num):
        window[i-1] = not window[i-1]

print(window.count(True))

- 이 문제 메모리 제한이 64MB다.

- 다른 문제는 128MB는 됐는데 작다. 그런데도 나는 for문을 중첩시켜서 계산했다.

- 여튼 그래서 N이 매우 큰 경우에는 안 맞는 코드인지 메모리 초과가 떴다.

- 사실 정답이 아닌 걸 보고 새 코드를 작성하는 데에 시간이 한참 걸렸다. 딱히 좋은 아이디어가 생각나지 않았음.

- 이면지에 창문 그려서 닫고 - 열고 순서대로 작성해봤다.

- 그리고 이 문제의 난이도를 다시 보니까 갑자기 좋은 생각이 났다.

- 사람이 홀수명이 조작하면 창문이 열린다는 거...

- 근데 또 홀수명이 조작하는 경우가 언제인지는 한참 종이에 쓰고 알아차렸다.

import math

n = int(input())

# sqrt 함수를 사용하여 주어진 n이하의 완전제곱수 개수를 계산.
result = int(math.sqrt(n))

print(result)

- 코드는 넘나 간단하다.

 

문제 접근 / 풀이

- 문제의 핵심은 '어떤 창문이 마지막에 열려 있는가'이다.

- 창문이 열리거나 닫히는 것은 해당 창문 번호의 약수에 해당하는 사람들이 행동할 때 발생한다.

- 물론 0명이 조작하는 경우는 안 된다(창문의 디폴트 값이 닫혀있기 때문에 한 번은 열려야 함.)

- 그리고 창문이 최종적으로 열려 있으려면, 창문을 조작하는 사람의 수가 홀수여야 한다.

- 창문을 조작하는 사람의 수가 홀수인 경우는 그 창문의 번호가 완전제곱수인 경우이다

- 완전제곱수를 제외한 다른 숫자들은 모두 짝수 개의 약수를 가지기 때문.

- 여기에 대해서 좀 더 주저리 설명 ↓

더보기

- 완전 제곱수 : 1, 4, 9, 16등..

 

- 완전제곱수가 아닌 숫자들 중 8을 예로 들면,

- 약수 하나를 구하면(ex.2) 그 약수에 매칭되는 또 다른 약수(ex.4)가 있다 => 필연적으로 2개씩 약수가 생겨난다

 

- 하지만 완전제곱수는 약수가 되는 제곱근 1개로 인해 전체 약수의 개수가 홀수 개일수 있다.

- 즉, 1부터 n까지의 창문들 중 n의 약수 창문들이 열리거나 닫히고,

- 그 열리거나 닫히는 창문들 중에서 완전제곱수 번호의 창문들만 최종적으로 열려있게 된다.

- 그래서 N이하의 완전제곱수의 개수를 찾는 코드를 작성하면 된다 => 이는 sqrt(N)을 계산하여 내림한 값이다.

 

결과

- 백준 문제 난이도를 띄울 수 있는 방법이 있어서 적용해봤다.

- 알고는 있었는데 여태 쉬운 문제들만 풀었는데도 바로 못 맞은 게 꽤 되네 쩝...

- 그래두 천리길도 한 걸음부터라고...? 늘겠지~~?!

- 이번엔 2-try.

728x90
반응형