백준 11653번 소인수분해 문제

 

225476KB, 1360MS로 해결

 

이전 포스팅 한 소수 구하기를 응용하여 풀 수 있다.

 

주어진 수를 소수의 작은 순서로 나누어 떨어지는 데 까지 나누고

마지막 남은 나머지가 소수 리스트 안에 있다면 해결

소수 리스트 안에 없다면 소인수 분해가 불가능 하다고 판단.

 

import math
n = int(input())
array = [True for i in range(n + 1)]

for i in range(2, int(math.sqrt(n)) + 1):
    if array[i]:
        j = 2
        while i * j <= n:
            array[i * j] = False
            j += 1


data = []
for i in range(2, n + 1):
    if array[i]:
        data.append(i)

while True:
    if n in data:
        print(n)
        break

    elif n == 1:
        break

    for i in range(2, n + 1):
        if n % i == 0:
            n //= i
            print(int(i))
            break

백준 2581번 소수 문제
124504kb, 120ms로 해결

 

주어진 범위 내에서 소수를 찾아, 그 소수들의 합과 최소값을 가지는 소수를 출력하는 문제이다.

에라토스테네스의 체 알고리즘을 이용하여 소수를 구해주면 된다.

 

에라토스테네스의 체는 N보다 작거나 같은 모든 소수를 찾을 때 사용할 수 있다.

1) 2부터 N까지 모든 자연수를 나열

2) 남은 수 중 아직 처리하지 않은 가장 작은 수 i를 찾는다.

3) 남은 수 중에서 i의 배수를 모두 제거한다.

4) 더이상 반복할 수 없을 때 까지 2, 3을 반복

 

시간 복잡도는 O(NloglogN)으로 선형 시간에 필적할 수준.

하지만 메모리를 많이 잡아먹는 단점이 있으니 잘 확인해보아야 한다.

파이썬 4796번 캠핑 문제

 

기본적인 수학 공식을 사용하면 바로 풀리는 문제였다.

 

l, p, v가 주어졌을 때, (v // p) * l에서 대부분이 정해지고

남은 일자가 l보다 크다 작다에 따라서 상세값이 정해진다.

 

따라서 v - (v // p) * p < l 일 경우 위 값에 더해주면 되고

아닐 경우 l을 더해주면 된다.

 

count = 1
while True:
    l, p, v = map(int, input().split())
    if l == p == v == 0:
        break
    result = (v // p) * l
    if v - (v // p) * p < l:
        result += v - (v // p) * p
    else:
        result += l

    print("Case %d:" %count, result)
    count += 1

백준 10610번 30 문제

 

 

 

이 문제를 보자마자, 아 permutation을 써서 나올 수 있는 모든 경우의 수중 30으로 나누어 떨어지는 수의

최대 값이 정답이겠구나! 라는 생각이 들어 코드를 짜보았으나.. 결과는 시간초과였다.

 

최초 코드의 시간 초과

 

from itertools import permutations
n = input()
data = []

for i in permutations(n, len(n)):
    tmp = int("".join(i))
    if tmp % 30 == 0:
        data.append(tmp)

if data:
    print(max(data))
    exit()

print("-1")

 

시간 초과가 된 코드는 바로 이것인데, 순열의 경우의 수가 10^5 까지 간다면, 그만큼 시공간 복잡도의 수가 기하급수적으로 늘어나게 됨을 간과하였다.

 

 

 

 

 

문제를 다시 곰곰히 살펴보니, 30의 배수가 되는 가장 큰 수 를 만들라는게 제일 큰 힌트였다.

 

30의 배수 -> 3의 배수 이면서 10의 배수.

결국 최대 값이면서, 맨 오른쪽 끝이 0으로 끝나야하니

입력받은 값을 역순으로 정렬하여 그 값이 30으로 나누어 떨어지기만 하면 되는 것이다.

 

n = list(input())
n.sort(reverse = True)
n = int("".join(n))
if n % 30 == 0:
    print(n)
else:
    print("-1")

수정 후 정답 코드

이렇게 쉽게 풀수 있었던 걸 너무 고전하였던 것 같다.

문제를 잘 읽어보는 습관을 들이자.

+ Recent posts