백준
백준 17436 소수의 배수
콩순이냉장고
2022. 1. 27. 18:36
문제 URL : https://www.acmicpc.net/problem/17436
17436번: 소수의 배수
첫째 줄에 N(1 ≤ N ≤ 10)과 M(1 ≤ M ≤ 1012)이 주어진다. 둘째 줄에는 N개의 소수가 주어진다. 입력으로 주어지는 소수는 100보다 작거나 같으며, 같은 소수가 두 번 이상 주어지지 않는다.
www.acmicpc.net
문제 접근법 : 이문제를 해결하기위해
포함배제의 원리라는 이론을 알아야 합니다. 그이론을 설명하기에는 무리가 있으니
이공식을 이용해야합니다.
소수의 집합을 v[i]={입력소수들} 이라할때
소수가 하나일때를 생각하면 1~M 이하까지의 소수의 배수들의 개수는
M/v[0] 입니다. 그러나
소수가 2개일때면
N(A)= M/v[0]
N(B) = M/v[1];
이지만 N(AUB) = N(A)+N(B) - N(AnB) 가 됩니다.
즉 소수 2,3일대
n(A) = M/2
n(B) = M/3
N(AnB) = M/6
입력받은 소수들은 전부 서로소이기때문에 그냥 전부 곱해줘도 상관없습니다.
따라서 위의 공식대로 소스코드를 구현하면
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
//By 콩순이냉장고
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n, m;
vector<ll> v;
ll res = 0;
void input() {
cin >> n >> m;
v.resize(n);
for (int i = 0; i < n; i++)
cin >> v[i];
}
void cal(int idx,int h,int h2=0,ll mul=1) {
if (h2 >= h) {
ll p = h % 2 == 0 ? -1 : 1;
res += p*(m / mul);
return;
}
for (int i = idx; i < n; i++) {
cal(i + 1, h, h2 + 1, mul * v[i]);
}
}
void solve() {
for (int i = 0; i < n; i++) {
cal(0, i+1);
}
cout << res << "\n";
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
input();
solve();
}
|
cs |
궁금한점 혹은 모르는점 논리적인 오류등 어떤 질문이든 댓글은 언제나 환영입니다.
사진 출처 : https://j1w2k3.tistory.com/987