※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 25632번 문제인 소수 부르기 게임이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/25632
먼저 1000 이하의 각 양의 정수가 소수인지를 판별해두자. 개수가 적으므로 각 정수 x를 x미만의 양의 정수로 각각 나누어떨어지는지 확인해도 문제를 해결하기에 충분하다. 글쓴이는 에라토스테네스의 체를 이용했다.
이제 용태가 부를 수 있는 수의 범위에 있는 소수의 개수, 유진이가 부를 수 있는 수의 범위에 있는 소수의 개수와 둘다 부를 수 있는 소수의 개수를 각각 구해두자.
용태와 유진이의 최선의 전략은 "둘다 부를 수 있는 소수"들을 먼저 부르고 남은 부를 수 있는 소수(자신만이 부를 수 있는 소수)들을 나중에 부르는 것이다. 자신의 차례가 지날 때마다 "자신이 부를 수 있는 소수"의 개수는 똑같이 하나씩 줄어들게 되는데 이 때 "상대방이 부를 수 있는 소수"의 개수를 하나 더 줄일 수 있는지 없는지의 여부에 차이점이 있다고 생각하면 이해하기 쉬울 것이다.
아래는 제출한 소스코드이다.
#include <iostream>
using namespace std;
int sieve[1001];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
sieve[0] = sieve[1] = 1;
for (int i = 2; i < 1001; i++) {
if (sieve[i]) continue;
for (int j = i * i; j < 1001; j += i) sieve[j] = 1;
}
int L1, R1, L2, R2; cin >> L1 >> R1 >> L2 >> R2;
int L3 = max(L1, L2), R3 = min(R1, R2);
int yt = 0, yj = 0, common = 0;
for (int i = L1; i <= R1; i++) {
if (sieve[i] == 0) yt++;
}
for (int i = L2; i <= R2; i++) {
if (sieve[i] == 0) yj++;
}
for (int i = L3; i <= R3; i++) {
if (sieve[i] == 0) common++;
}
while (1) {
if (yt + common == 0) {
cout << "yj";
return 0;
}
if (common) yt--, common--, yj--;
else yt--;
if (yj + common == 0) {
cout << "yt";
return 0;
}
if (common) yt--, common--, yj--;
else yj--;
}
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 25639 // C++] 수열과 최대 상승 쿼리 (0) | 2022.11.03 |
---|---|
[BOJ 25637 // C++] 회전 목마 (0) | 2022.11.02 |
[BOJ 25630 // C++] 팰린드롬 소떡소떡 (0) | 2022.10.31 |
[BOJ 25828 // C++] Corona Virus Testing (0) | 2022.10.30 |
[BOJ 13496 // C++] The Merchant of Venice (0) | 2022.10.30 |