728x90
SMALL
백준 문제 풀이: 2981 [검문]
문제 링크: https://www.acmicpc.net/problem/2981
문제 설명:
n개의 숫자가 주어질 때, 이를 m으로 나눴을 때 모두 같은 나머지를 가지는 m의 가능한 값을 오름차순으로 출력하는 문제입니다. 여기서 m은 1보다 커야 합니다.
문제 해결 코드
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
int arr[101];
set<int> s;
// 최대공약수 계산 함수
int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
// 숫자 입력
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
// 배열 정렬
sort(arr, arr + n);
// 모든 인접 차이의 최대공약수 계산
int k;
if (n == 2) {
k = arr[1] - arr[0];
} else {
k = gcd(arr[1] - arr[0], arr[2] - arr[1]);
for (int i = 3; i < n; i++) {
k = gcd(k, arr[i] - arr[i - 1]);
}
}
// 최대공약수의 약수 찾기
for (int i = 2; i * i <= k; i++) {
if (k % i == 0) {
s.insert(i);
s.insert(k / i);
}
}
s.insert(k);
// 결과 출력
for (auto iter = s.begin(); iter != s.end(); iter++) {
cout << *iter << ' ';
}
}
코드 설명
- 핵심 알고리즘: 인접 차이의 최대공약수를 활용해 모든 숫자를 나눌 수 있는 m의 약수를 구합니다.
- 구현 세부사항:
- 입력된 숫자를 정렬하여 인접한 숫자들의 차이를 계산
- 모든 차이의 최대공약수를 구하고, 이를 약수로 나눕니다.
- 구한 약수는 set 자료구조를 이용하여 중복 없이 저장 후 정렬 출력합니다.
- 시간 복잡도:
- 입력 정렬: O(n log n)
- 최대공약수 계산: O(n log k), 여기서 k는 최대공약수
- 약수 계산: O(√k)
결과
주어진 숫자들로부터 조건을 만족하는 m의 값을 오름차순으로 출력합니다. 문제를 해결하기 위해 최대공약수를 기반으로 약수를 구하는 접근법을 사용했습니다.
다른 접근 방식이나 개선 사항이 있다면 댓글로 공유 부탁드립니다!
728x90
LIST
'BAEKJOON > 수학' 카테고리의 다른 글
백준 1188번 [음식 평론](C++)-yes6686- 티스토리 (1) | 2024.01.11 |
---|---|
백준 2485번 [가로수](C++)-yes6686- 티스토리 (0) | 2024.01.11 |
백준 15377번 [Bounce Bounce Bounce](C++)-yes6686- 티스토리 (1) | 2024.01.06 |
백준 18110번 [solved.ac](C++)-yes6686- 티스토리 (0) | 2024.01.05 |
백준 11650번 [좌표 정렬하기](C++)-yes6686- 티스토리 (1) | 2024.01.05 |