#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int MAX_NUM = 1000001;
int PLAYERS;
vector<int> card_numbers;
bool if_player_has_card[MAX_NUM];
int scores[MAX_NUM];
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> PLAYERS;
for (int i = 0; i < PLAYERS; i++)
{
int card_num;
cin >> card_num;
// vector에 값을 추가할 때, push_back이 아닌 emplace_back을 사용하면 벡터에 직접 객체를 생성하여 추가
// 값을 복사하지 않으므로 더 효율적(단순한 데이터타입이면 큰 차이는 없음)
card_numbers.emplace_back(card_num);
if_player_has_card[card_num] = 1;
}
// PLAYERS의 숫자만큼 반복하므로 O(N)의 시간복잡도
for (int i = 0; i < PLAYERS; i++)
{
// 최악의 경우 O(MAX_NUM * (1/2 + 1/3 + ... + 1/(MAX_NUM-1)))
// = 조화급수(harmonic series)
// = O(logN)의 시간복잡도
for (int j = card_numbers[i] * 2; j < MAX_NUM; j += card_numbers[i])
{
if (if_player_has_card[j])
{
scores[card_numbers[i]]++; // 소수를 가진 사람이 승리
scores[j]--; // 배수를 가진 사람은 패배
}
}
} // 2중 for문을 사용하였으므로 전체 풀이는 O(N*logN)의 시간복잡도를 가진다.
for (int i = 0; i < PLAYERS; i++)
cout << scores[card_numbers[i]] << " ";
return 0;
}
문제에서 테스트 케이스가 다음과 같이 주어졌는데
예제 1에서는
3
3 4 12
로 입력값이 주어졌다.
3을 가진 플레이어가 있으므로
6, 9, 12, 15, ... 등 3의 배수를 가진 플레이어는 -1이 된다.
예시에서 12를 가진 플레이어가 있으므로 3을 가진 플레이어의 점수는 +1이다.
또, 4를 가진 플레이어가 있으므로
4, 8, 12, 16, ... 등 4의 배수를 가진 플레이어는 -1이 된다.
예시에서 12를 가진 플레이어가 있으므로 4를 가진 플레이어의 점수는 +1이고,
12를 가진 플레이어는 한 번 더 패배해서 -2가 된다.
예제 2에서는
4
7 23 8 6
로 입력값이 주어졌다.
7의 배수인 14, 21, 28, ... 이 존재하지 않으므로 7을 가진 플레이어의 점수는 0
23, 8, 6도 마찬가지로 0이다.