728x90
728x90
배수(Multiple)와 약수(Divisor)
배수(Multiple)
- 어떤 수에다 1배, 2배, 3배, 4배, ... 한 수들을 그 수의 배수(Multiple)라고 한다.
- 예) {3, 6, 9, ...} 는 3의 배수이다.
예제
1부터 100 사이의 3의 배수 출력하기
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 100; i++) {
if (i % 3 == 0) {
cout << i << " ";
}
}
return 0;
}
3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84 87 90 93 96 99
약수(Divisor)
- 어떤 수를 나누었을 때, 나누어 떨어지게 하는 자연수를 어떤 수의 약수(Divisor)라고 한다.
- 또한 모든 수는 1로 나누었을 때, 나누어 떨어지므로 1은 모든 수의 약수이다.
- 예) 1, 2, 3, 4, 6, 12로 12를 나누게 되면 12는 나누어 떨어지므로 1, 2, 3, 4, 6, 12는 12의 약수이다.
단순한 방법으로 약수 구하기
- 약수를 구하려는 값(@N@)을 @1@부터 @N@까지의 숫자로 나누면서, 나머지가 0인 값을 약수로 처리하는 방법이다.
- 이 방법은 $O(N)$ 의 시간 복잡도를 갖는다.
예제
12의 약수 출력하기
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 12; i++) {
if (12 % i == 0) {
cout << i << " ";
}
}
return 0;
}
1 2 3 4 6 12
효율적으로 약수 구하기
- 약수를 구하려는 값(@N@)을 @1@부터 @$sqrt(N)$@까지의 숫자로 나누면서, 나머지가 0인 값과 몫이 0인 값들을 약수로 처리하는 방법이다.
- 이 방법은 $O(\sqrt{N})$ 의 시간 복잡도를 갖는다.
예
- 10의 약수를 찾는 경우를 생각해보자.
10 % 1 = 0
10 % 2 = 0
10 % 3 = 1
10 % 4 = 2
10 % 5 = 0
10 % 6 = 4
10 % 7 = 3
10 % 8 = 2
10 % 9 = 1
10 % 10 = 0
- 10이 0으로 나누어 떨어지게 하는 수는 @1@, @2@, @5@, @10@으로, 이는 10의 약수에 해당한다.
- 이 과정은 @1@부터 @10@까지의 모든 수를 이용하여 약수를 찾으므로, $O(N)$ 의 시간 복잡도를 갖는다.
- 100의 약수를 찾는 경우를 생각해보자.
- 우선, 100을 1부터 100의 제곱근($\sqrt{100}$)인 $10$ 까지 숫자로 나눈 나머지를 살펴보자.
100 % 1 = 0
100 % 2 = 0
100 % 3 = 1
100 % 4 = 0
100 % 5 = 0
100 % 6 = 4
100 % 7 = 2
100 % 8 = 4
100 % 9 = 1
100 % 10 = 0
- 위의 과정을 통해서 100의 약수는 일단 @1@, @2@, @4@, @5@, @10@을 갖는다는 것을 확인할 수 있다.
- 이제 100에 이미 구해진 약수들을 나누어(@/@) 보자.
100 / 1 = 100
100 / 2 = 50
100 / 4 = 25
100 / 5 = 20
100 / 10 = 10
- 이 과정을 통해 나머지 약수들(@10@, @20@, @25@, @50@, @100@)을 구할 수 있음을 확인할 수 있다.
- 단, 약수 @10@이 2번 중복되므로, 중복 처리를 해줘야 한다.
- @약수를 구하려는 값 / 나누는 값 = 나누는 값@일 경우, 약수로 처리해주지 않는다.
- 이 방법은 시간 복잡도가 $O(\sqrt{N})$ 이므로, 10억개의 입력이 들어온다고 해도 약 3만번의 연산으로 약수를 구할 수 있다. 따라서, 코딩 테스트 문제를 풀 때 시간 초과가 발생하는 일은 없다.
예제
100의 약수 출력하기
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> divs;
int main() {
for (int i = 1; i <= sqrt(100); i++) {
if (100 % i == 0) {
divs.push_back(i);
if (i != 100 / i) { // 중복 처리
divs.push_back(100 / i);
}
}
}
// 오름차순 정렬
sort(divs.begin(), divs.end());
for (auto i : divs) {
cout << i << " ";
}
return 0;
}
1 2 4 5 10 20 25 50 100
728x90
728x90
'Computer Science > 알고리즘' 카테고리의 다른 글
[Algorithm] 콜라츠 추측(Collatz Conjecture) ; 우박수(Hailstone Sequence), 3N + 1 Problem (0) | 2022.09.01 |
---|---|
[Algorithm] 소수(Prime Number) ; 쌍둥이 소수(Twin Primes), 메르센 소수(Mersenne Primes), 골드바흐의 추측(Goldbach's Conjecture) (0) | 2022.09.01 |
[Algorithm] 팰린드롬(Palindrome) (0) | 2022.09.01 |
[Algorithm] 완전제곱수(Perfect Square Number, 제곱수, 정사각수) (0) | 2022.08.31 |
[Algorithm] 팩토리얼(Factorial) (0) | 2022.08.31 |
[Algorithm] 완전수(Perfect Number), 부족수(Deficient Number), 과잉수(Abundant Number) (0) | 2022.08.31 |
[Algorithm] 가우스 계산법(Gaussian Calculation) (0) | 2022.08.31 |
[Algorithm] 알고리즘이란? (0) | 2022.06.24 |