Skip to content

Commit 6255ca3

Browse files
authored
Create BOJ1016.md
1 parent a6b5af7 commit 6255ca3

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

challenges/BOJ1016.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# 문제
2+
제곱 ㄴㄴ 수
3+
## 문제 원본
4+
문제의 원본은 [여기서](https://www.acmicpc.net/problem/1016) 확인하세요.
5+
6+
## 분류
7+
* 제곱 ㄴㄴ 수
8+
9+
# 풀이
10+
11+
에라토스테네스의 체를 이용하여 제곱수를 걸러낸다. 그 이후 (max - min + 1)에서 체에서 걸러내진 개수를 뺀다.
12+
즉, min ~ max 사이의 개수에서 제곱수의 개수를 빼면 제곱 ㄴㄴ 수의 개수가 된다.
13+
14+
``` c++
15+
#include <iostream>
16+
#include <cmath>
17+
18+
using namespace std;
19+
20+
bool counted[1000001] = { false };
21+
22+
int main(void) {
23+
ios::sync_with_stdio(false);
24+
cin.tie(0); cout.tie(0);
25+
26+
long long min, max;
27+
cin >> min >> max;
28+
29+
// 제곱수의 수
30+
long long count = 0;
31+
32+
// 2부터 i^2 <= max까지 제곱수의 배수를 카운트
33+
for (long long i = 2; i * i <= max; i++) {
34+
// 에라토스테네스의 체에서 min 이상의 값만 검사하면 되므로,
35+
// i^2 * n를 했을때 min 이상이 되는 첫 n를 구한다.
36+
long long n = min / (i * i);
37+
// n이 min 이하일경우
38+
if (n * i * i < min) n++;
39+
40+
// i제곱의 배수를 카운트 (max 이하까지만)
41+
for (long long j = n; i * i * j <= max; j++) {
42+
// counted 배열을 위해 (min ~ max)를 0 ~ (max -min) 으로 대응
43+
long long idx = i * i * j - min;
44+
45+
// 중복 카운트 방지
46+
if (!counted[idx]) {
47+
count++;
48+
counted[idx] = true;
49+
//cout << i * i * j << endl;
50+
}
51+
}
52+
}
53+
54+
int result = (max - min + 1) - count;
55+
56+
cout << result << "\n";
57+
58+
return 0;
59+
}
60+
```

0 commit comments

Comments
 (0)