2981번: 검문
트럭을 타고 이동하던 상근이는 경찰의 검문을 받게 되었다. 경찰은 상근이가 운반하던 화물을 하나하나 모두 확인할 것이기 때문에, 검문하는데 엄청나게 오랜 시간이 걸린다. 상근이는 시간��
www.acmicpc.net
ar 배열에 입력받은 수들을 정렬해주고
어떤 수 ar[i] = 몫*나눈값+나머지 이므로 나머지를 처리해줘야 하니
ar[i] - ar[i-1] = 나눈값(몫-몫2) + (나머지-나머지) 이다
나눌 값들은 각각에 배열들에 대해 최대공약수를 구해서 그 최대공약수의 약수들로 나눠주면 같은 나머지가 출력된다.
#include <iostream> #include <vector> #include <algorithm> using namespace std; int GCD(int x, int y) { if (y == 0) return x; return GCD(y, x % y); } int main() { int n, gcd; vector<int> ar, ans; cin >> n; for (int i = 0; i < n; i++) { int x; cin >> x; ar.push_back(x); } sort(ar.begin(), ar.end()); gcd = ar[1] - ar[0]; for (int i = 2; i < n; i++) gcd = GCD(gcd, ar[i] - ar[i - 1]); for (int i = 2; i * i <= gcd; i++) { if (gcd % i == 0) { ans.push_back(i); ans.push_back(gcd / i); } } ans.push_back(gcd); sort(ans.begin(), ans.end()); ans.erase(unique(ans.begin(), ans.end()), ans.end()); for (int i = 0; i < (int)ans.size(); i++) cout << ans[i] << ' '; return 0; }
유클리드 호제법을 전부 돌리고 나서 그 최대공약수에 대해 약수를 구해야 하는데 최댓값이 10억이라 그냥 구하면 TLE가 난다.
for (int i = 2; i * i <= gcd; i++) { if (gcd % i == 0) { ans.push_back(i); ans.push_back(gcd / i); } }
약수구하는 로직을 제곱을 통해 최적화를 해주고
포문을 1이 아닌 2부터 돌리니까 마지막 최대공약수가 포함되지 않는다. 따로 처리해줘야 한다.
sort(ans.begin(), ans.end()); ans.erase(unique(ans.begin(), ans.end()), ans.end());
각각의 약수들에 대해 정렬해서 unique함수를 통해 중복되는 수를 제거해주면 AC를 받는다.
'알고리즘 > BOJ' 카테고리의 다른 글
백준 2331 반복수열 (0) | 2020.09.08 |
---|---|
백준 10451 순열 사이클 (0) | 2020.09.07 |
백준 13305 주유소 (0) | 2020.09.07 |
백준 12865 평범한 배낭 (0) | 2020.09.07 |
백준 19621, 19622 회의실배정 2, 3 (0) | 2020.09.06 |