백준 문제를 풀던 중 약수에 대해 공부할 기회가 생겨 찾아보던 중에 에라토스테네스의 채와 같이 제곱근의 형태를 띄는 최적화를 알게 되었다.
for (int i = 1; i <= n; i++) {
if (n % i == 0) cout << i << ' ';
}
기본적인 약수 구하는 방법은 O(N)으로 구하려는 수가 i를 돌면서 나누어 떨어진다면 약수이다. 그러나 이 식으로는 21억같은 큰 수들은 꽤 오랜 시간이 걸린다.
이를 위해서 약수의 특성을 이용하여
for (int i = 1; i * i <= n; i++) {
if (n % i == 0) cout << i << ' ' << n / i << ' ';
}
이런 식으로 하여금 구할 수 있다.
int 형 범위의 대푯값인 21억을 넣어서 확인해봤다.


간단한 코드 차이지만 눈에 띄게 시간이 줄어든다.
#include <iostream>
#include <ctime>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int n;
vector<int> ar;
cin >> n;
clock_t start = clock();
//for (int i = 1; i <= n; i++) {
// if (n % i == 0) ar.push_back(i);
//}
//cout << endl;
for (int i = 1; i * i <= n; i++) {
if (n % i == 0) cout << i << ' ' << n / i << ' ';
}
cout << endl;
sort(ar.begin(), ar.end());
ar.erase(unique(ar.begin(), ar.end()), ar.end());
for (int i = 0; i < ar.size(); i++) cout << ar[i] << ' ';
cout << endl;
clock_t end = clock();
cout << "TIME: " << (end - start) / CLOCKS_PER_SEC << endl;
return 0;
}
약수일 때마다 벡터에 푸쉬해주고 정렬한 뒤 중복되는 수를 제거해서 출력해줬다.
'Algorithm' 카테고리의 다른 글
플로이드 - 와샬 알고리즘 (0) | 2020.10.19 |
---|---|
벨만 - 포드 알고리즘 (0) | 2020.10.18 |
유니온 파인드(Union-Find) (0) | 2020.10.15 |
순열과 조합 (0) | 2020.10.02 |
다익스트라 알고리즘 (0) | 2020.09.24 |