[백준] 검문

유의할점

풀이

M : 같은 나머지를 가지게 하는 수

N개의 수들은 다음과 같이 표현가능하다.

v[0] = q0_0

v[1] = q1_1

v[2] = q2_2

...

v[n-2] = q1_1

v[n-1] = q1_1

위의 식을 두 요소의 차로 표현하면

v[1] - v[0] = (q1_1

v[2] - v[1] = (q2_2

v[3] - v[2] = (q3_3

v[4] - v[3] = (q4_4

...

v[n-1] - v[n-2] = (qn1_{n-1}

로 표현 가능하다. 즉 두 요소의 차의 최대 공약수의 약수가 답이 되는 사실을 알 수 있다.

예를 들어, 최대공약수를 12라고 했을때. 12의 약수인 4가 M이 될수있는 이유는 다음 예시로 이해할수있다.

v[1] - v[0] = ((q1_1

v[2] - v[1] = ((q2_2

v[3] - v[2] = ((q3_3

v[4] - v[3] = ((q4_4

...

v[n-1] - v[n-2] = ((qn1_{n-1}

M이 5인 경우는 있을수없다. 5가 된다면, 공통요소에 포함되므로 공약수에 포함되어야하고, 최대 공약수의 약수가 되었어야 한다.

코드

C++

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void print_fnc(int n) {
	cout << n << " ";
}

int gcd(int a, int b) {
	return b ? gcd(b, a % b) : a;
}

int main() {
	int N;
	cin >> N;
	vector<int> arr(N);
	for (int i = 0; i < N; i++)
		cin >> arr[i];
	sort(arr.begin(), arr.end());
	int g = arr[1] - arr[0];
	for (int i = 2; i < N; i++)
		g = gcd(g, arr[i] - arr[i - 1]);
	//10억의 제곱근 = 3~4만
	vector<int> res;
	for (int i = 1; i * i <= g; i++) {
		if (g % i)
			continue;
		res.push_back(i);
		res.push_back(g / i);
	}
	sort(res.begin(), res.end());
	res.erase(unique(res.begin(), res.end()), res.end());
	for_each(res.begin() + 1, res.end(),print_fnc);
}

좋은 웹페이지 즐겨찾기