
브루트포스 알고리즘, 수학, 정수론, 소수 판정, 에라토스테네스의 체
《보드게임컵》을 준비하다 지친 은하는 보드게임컵 참가자들을 경기장에 몰아넣고 결투를 시키는 게임 《수 나누기 게임》을 만들었습니다.
《수 나누기 게임》의 규칙은 다음과 같습니다.
《수 나누기 게임》의 결과를 가지고 한별이와 내기를 하던 은하는 게임이 종료되기 전에 모든 플레이어의 점수를 미리 알 수 있을지 궁금해졌습니다. 은하를 위해 각 플레이어가 가지고 있는 카드에 적힌 수가 주어졌을 때, 게임이 종료된 후의 모든 플레이어의 점수를 구해주세요.
첫 번째 줄에 플레이어의 수 N이 주어집니다.
두 번째 줄에 첫 번째 플레이어부터 N
번째 플레이어까지 각 플레이어가 가지고 있는 카드에 적힌 정수 x1, ⋯, xN이 공백으로 구분되어 주어집니다.
첫 번째 플레이어부터 N번째 플레이어까지 게임이 종료됐을 때의 각 플레이어의 점수를 공백으로 구분하여 출력해주세요.
소수 판정에서 이용되는 에라토스테네스의 채 개념을 이용해서 문제를 풀 수 있었다. 결국 주어진 카드들 중에서 소수처럼 다른 수들로 나눠지지 않는 숫자만 점수를 얻는다는 아이디어를 통해서 해결할 수 있었다.
import java.io.*;
import java.util.*;
class Main {
public static final BufferedReader BR = new BufferedReader(new InputStreamReader(System.in));
public static final BufferedWriter BW = new BufferedWriter(new OutputStreamWriter(System.out));
int N;
int[] cards;
int[] toPrint;
int[] scores;
int maxCard;
HashSet<Integer> cardHashSet;
public static void main(String[] args) {
Main main = new Main();
try {
main.init();
main.solution();
} catch (Exception e) {
System.out.println("exception during I/O");
}
}
/*
카드의 숫자들을 전체 숫자라고 정의하고, 소수 여부를 판단하면되는 게임이 아닌가?
*/
void init() throws Exception {
N = Integer.parseInt(BR.readLine());
String inputArray = BR.readLine();
cards = Arrays.stream(inputArray.split(" ")).mapToInt(Integer::parseInt).toArray();
toPrint = Arrays.stream(inputArray.split(" ")).mapToInt(Integer::parseInt).toArray();
maxCard = Arrays.stream(cards).max().getAsInt();
scores = new int[maxCard+1];
cardHashSet = new HashSet<>();
Arrays.sort(cards);
for (int card : cards) {
cardHashSet.add(card);
}
}
void solution() throws Exception {
for (int card : cards) {
for (int i = card * 2; i <= maxCard; i += card) {
if (cardHashSet.contains(i)) {
scores[card] += 1;
scores[i] -= 1;
}
}
}
for (int card : toPrint) {
BW.write(scores[card]+" ");
}
BW.flush();
BW.close();
}
}