본문 바로가기

PS/백준

[BOJ] 백준 9506 약수들의 합 (Swift)

반응형

문제

https://www.acmicpc.net/problem/9506

 

9506번: 약수들의 합

어떤 숫자 n이 자신을 제외한 모든 약수들의 합과 같으면, 그 수를 완전수라고 한다. 예를 들어 6은 6 = 1 + 2 + 3 으로 완전수이다. n이 완전수인지 아닌지 판단해주는 프로그램을 작성하라.

www.acmicpc.net

풀이

먼저, 입력받은 n의 약수들을 구하는 로직을 작성해야 합니다.
n을 1 ~ n까지 하나씩 나누어 떨어지는지 확인하면서, 약수를 구하는 방법이 있지만,

1 ~ $\sqrt{n}$까지 확인하는 방법이 더 빠릅니다.

예를 들어 18 이라는 수가 있다면,
1 * 18
2 * 9
3 * 6
6 * 3
9 * 2
18 * 1
과 같이 대칭을 이룹니다.

$\sqrt{18}$은 약 4.2 입니다.

굳이 6, 9, 18 로 나누어 떨어지는지 확인할 필요가 없고 4까지만 확인한 후
나누어 떨어진다면 나누어 떨어지는 수와, 나누어진 몫약수가 됩니다.

이러한 약수들을 Int 배열에 담아줍니다.

두 가지 문제점이 있습니다.

한 가지는 36 같은 경우 6 * 6이므로, 6이 중복이 되어서 Int 배열에 6이 2번 등장하게 됩니다.
어떤 수의 제곱근인 경우, 중복이 되기 때문에 Set 자료형을 사용해 중복 제거를 해줍니다.

다른 한 가지는 자기 자신을 제외하여야 합니다.
자기 자신은 약수들 중 가장 큰 수이기 때문에,
중복을 제거한 배열을 오름차순으로 정렬한 후 마지막 요소를 제거해주면 됩니다.

이제 이 약수들의 합과 n이 동일한지 확인하고 출력해주면 됩니다.

reduce 메서드를 사용해 배열의 합을 구할 수 있고,
join 메서드를 사용해 배열의 요소 사이에 String 값넣어줄 수 있습니다.

소스코드

후기

약수를 구하는 방법에는 1 ~ n 까지 나누어 떨어지는지 확인해도 무방합니다.
하지만, 1 ~ $\sqrt{n}$ 까지 확인하는 것이 훨씬 빠릅니다.

또한, reduce메서드를 사용하지 않고도, 배열의 요소의 합을 구할 수 있습니다. (for문 사용 등)
join 메서드를 사용하지 않고도 " + "를 요소 사이에 넣어줄 수 있습니다.

하지만 위 두 메서드를 사용하는 편이 직관적이고 코드의 크기를 줄일 수 있다고 느꼈습니다.

반응형