[BOJ] 27172 수 나누기 게임 (node.js)

2025. 1. 22. 13:42·👩‍💻 Algorithm
BOJ 문제 27172번의 풀이 과정을 작성한 게시글입니다.

 

링크

https://www.acmicpc.net/problem/27172

 

문제

《보드게임컵》을 준비하다 지친 은하는 보드게임컵 참가자들을 경기장에 몰아넣고 결투를 시키는 게임 《수 나누기 게임》을 만들었습니다.《수 나누기 게임》의 규칙은 다음과 같습니다.

 

게임을 시작하기 전 각 플레이어는 1부터 1000000 사이의 수가 적힌 서로 다른 카드를 잘 섞은 뒤 한 장씩 나눠 가집니다.

매 턴마다 플레이어는 다른 플레이어와 한 번씩 결투를 합니다.

결투는 서로의 카드를 보여주는 방식으로 진행되며, 플레이어의 카드에 적힌 수로 다른 플레이어의 카드에 적힌 수를 나눴을 때, 나머지가 0$0$이면 승리합니다. 플레이어의 카드에 적힌 수가 다른 플레이어의 카드에 적힌 수로 나누어 떨어지면 패배합니다. 둘 다 아니라면 무승부입니다.

승리한 플레이어는 1점을 획득하고, 패배한 플레이어는 1점을 잃습니다. 무승부인 경우 점수의 변화가 없습니다.

본인을 제외한 다른 모든 플레이어와 정확히 한 번씩 결투를 하고 나면 게임이 종료됩니다.

《수 나누기 게임》의 결과를 가지고 한별이와 내기를 하던 은하는 게임이 종료되기 전에 모든 플레이어의 점수를 미리 알 수 있을지 궁금해졌습니다. 은하를 위해 각 플레이어가 가지고 있는 카드에 적힌 수가 주어졌을 때, 게임이 종료된 후의 모든 플레이어의 점수를 구해주세요.

 

풀이 과정

접근법 1. 조합

모든 플레이어들이 한 번씩 게임을 진행해야 하기 때문에,

가장 간단하게는 모든 플레이어들의 게임을 모두 한 번씩 진행시키는 방법이 있다.

 

하지만 이는 전체 인원이 최대 10,000명인 것을 고려하면 시간 초과가 발생하게 된다.

 

접근법 2. 각 수의 배수를 구해서 처리하기

게임에서 이기는 경우와 지는 경우를 정리하면 다음과 같다.

나 A B
3 6 12

 

나와 A가 결투를 할 때

6을 3으로 나눈 나머지는 0이므로 내가 승리한다.

그리고 A는 패배한다.

 

나와 B가 결투를 할 때도 마찬가지로

12를 3으로 나눈 나머지는 0이므로 내가 승리한다.

그리고 B는 패배한다.

 

즉, 내가 이기는 경우의 수는 내 카드의 배수가 되는 수를 다른 참가자들이 몇개를 가지고 있는지를 통해 승리 횟수를 미리 구할 수 있다.

 

나는 현재 플레이어 카드의 배수가 되는 수를 순회하면서,

배수가 다른 플레이어 중에서 존재한다면 승리 횟수를 높이고, 반대로 해당 배수의 패배 횟수를 추가(점수에 -1)했다.

 

 

코드

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
const input = require("fs").readFileSync(filePath).toString().trim().split("\n");

const nums = input[1].split(" ").map(Number);
const isExist = Array.from({ length: 1000001 }, () => false);
const score = Array.from({ length: 1000001 }, () => 0);

for (let num of nums) {
  isExist[num] = true;
}

for (let num of nums) {
  for (let i = num * 2; i <= 1000000; i += num) {
    if (isExist[i]) {
      score[num]++;
      score[i]--;
    }
  }
}

const answer = [];

for (let num of nums) {
  answer.push(score[num]);
}

console.log(answer.join(" "));

 

후기

처음에는 n^2라고 생각해서 시간 초과가 날 수도 있겠다고 생각했는데, 이중 포문 내부의 연산 횟수가 n이 아니라 logn에 가깝기 때문에 시간 초과가 발생하지 않았다.

'👩‍💻 Algorithm' 카테고리의 다른 글

[BOJ] 16928 뱀과 사다리 게임 (node.js)  (2) 2025.01.24
[BOJ] 18808 스티커 붙이기 (node.js)  (0) 2025.01.23
[BOJ] 1520 내리막 길 (node.js)  (0) 2025.01.21
[BOJ] 2056 작업 (node.js)  (2) 2025.01.20
[BOJ] 1240 노드사이의 거리 (node.js)  (0) 2025.01.17
'👩‍💻 Algorithm' 카테고리의 다른 글
  • [BOJ] 16928 뱀과 사다리 게임 (node.js)
  • [BOJ] 18808 스티커 붙이기 (node.js)
  • [BOJ] 1520 내리막 길 (node.js)
  • [BOJ] 2056 작업 (node.js)
fe developer
fe developer
Every second counts 🫧
  • fe developer
    메리의 코딩일기장
    fe developer
  • 전체
    오늘
    어제
    • 분류 전체보기 (27)
      • ☘️ Front end (4)
        • 🌱 React (0)
        • 🌱 Javascript (4)
        • ✨ Deep dive (0)
      • 🪐 우아한테크코스 (0)
      • 👩‍💻 Algorithm (14)
      • 💻 CS (9)
        • 🫧 네트워크 (6)
        • 🫧 운영체제 (0)
        • 🫧 컴퓨터구조 (3)
      • 💭 회고록 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    2024
    computer structure
    BOJ
    실행 컨텍스트
    DP
    BFS
    Algorithm
    this
    CS
    연간회고록
    dfs
    JavaScript
    network
    네트워크
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
fe developer
[BOJ] 27172 수 나누기 게임 (node.js)
상단으로

티스토리툴바