Skip to content

[구현] 상어 초등학교 #90

@ericagong

Description

@ericagong

⭐ 성찰

  1. 시간 복잡도 감소시키기 위해, 특정 값의 존재 여부를 바로 확인해야하면 set/map 타입 사용하기 ⭐ 배열 지양 ⭐
  2. 완전 탐색이 필요한 경우, 반드시 시간 복잡도를 먼저 생각해 (1) 가능한지 (2) 탐색 시간을 줄일 수 있는 방법은 무엇이 있을지 고민해야함

❓ 문제 상황

상어 초등학교

👨‍💻 문제 해결

✅ 1차 풀이: 구현

⏳ 시간 복잡도 계산

[시간복잡도]
n*2 * n*2 * nlogn = O(n*5logn), 
학생 수 * 최대 빈 자리 * 정렬
-> 3 ≤ N ≤ 20 이므로 4,163,295 <= 10,000,000
-> JS는 코테 환경에서 1초에 1000만 내의 연산 수행 가능
-> `완전탐색` 가능
  1. 정해진 순서대로 학생별 최적 자리 구하기
  • 학생 별 좋아하는 학생 4명을 map에 key = 학생 index, value = 좋아하는 학생 set으로 저장
  • ** 배열이 아닌 set을 사용해 set.prototype.has로 특정 값에 바로 접근하게 함 **
  • 모든 빈 자리에 대해 [numFav, numEmpty, x, y] 형태의 정보를 만들고, 정렬하여 최적 자리 구하기
  1. 전체 자리에 대해 만족도 계산
const fs = require("fs");
const inputs = fs.readFileSync("/dev/stdin").toString().split("\n");

const N = Number(inputs.shift());
const g = Array.from({ length: N }, () => new Array(N).fill(0));

const favs = new Map();
const orders = [];
for (let i = 0; i < N * N; i++) {
  const [num, ...fav] = inputs.shift().split(" ").map(Number);
  orders.push(num);
  favs.set(num, new Set(fav));
}

// 디버깅용 로거
// function log() {
//   for(let i = 0; i < g.length; i++) {
//     console.log(g[i].join(' '))
//   }
//   console.log()
// }

const dx = [-1, 1, 0, 0];
const dy = [0, 0, -1, 1];
// log()

// 모든 학생에 대해 적절한 자리 찾기
orders.forEach((num) => {
  const targets = [];
  for (let x = 0; x < N; x++) {
    for (let y = 0; y < N; y++) {
      if (g[x][y] !== 0) continue;

      let num_fav = 0;
      let num_empty = 0;
      for (let i = 0; i < 4; i++) {
        const nx = x + dx[i];
        const ny = y + dy[i];

        if (nx < 0 || ny < 0 || nx >= N || ny >= N) continue;
        if (g[nx][ny] === 0) num_empty += 1;
        else if (favs.get(num).has(g[nx][ny])) num_fav += 1;
      }

      targets.push([num_fav, num_empty, x, y]);
    }
  }

  // 최적의 자리 선택 위해 문제 조건대로 정렬
  targets.sort((a, b) => {
    if (a[0] !== b[0]) return b[0] - a[0];
    if (a[1] !== b[1]) return b[1] - a[1];
    if (a[2] !== b[2]) return a[2] - b[2];
    return a[3] - b[3];
  });

  const [_, __, tx, ty] = targets[0];
  g[tx][ty] = num;
});

// log()

// 전체 만족도 계산
let satisfaction = 0;
for (let x = 0; x < N; x++) {
  for (let y = 0; y < N; y++) {
    const num = g[x][y];
    let num_fav = 0;

    for (let i = 0; i < 4; i++) {
      const nx = x + dx[i];
      const ny = y + dy[i];

      if (nx < 0 || ny < 0 || nx >= N || ny >= N) continue;
      if (favs.get(num).has(g[nx][ny])) num_fav += 1;
    }

    if (num_fav === 0) continue;
    else satisfaction += Math.pow(10, num_fav - 1);
  }
}

console.log(satisfaction);

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions