백준

[실버] 유기농 배추 (1012번)_JS

chsua 2022. 12. 19. 17:53

문제

차세대 영농인 한나는 강원도 고랭지에서 유기농 배추를 재배하기로 하였다. 농약을 쓰지 않고 배추를 재배하려면 배추를 해충으로부터 보호하는 것이 중요하기 때문에, 한나는 해충 방지에 효과적인 배추흰지렁이를 구입하기로 결심한다. 이 지렁이는 배추근처에 서식하며 해충을 잡아 먹음으로써 배추를 보호한다. 특히, 어떤 배추에 배추흰지렁이가 한 마리라도 살고 있으면 이 지렁이는 인접한 다른 배추로 이동할 수 있어, 그 배추들 역시 해충으로부터 보호받을 수 있다. 한 배추의 상하좌우 네 방향에 다른 배추가 위치한 경우에 서로 인접해있는 것이다.

한나가 배추를 재배하는 땅은 고르지 못해서 배추를 군데군데 심어 놓았다. 배추들이 모여있는 곳에는 배추흰지렁이가 한 마리만 있으면 되므로 서로 인접해있는 배추들이 몇 군데에 퍼져있는지 조사하면 총 몇 마리의 지렁이가 필요한지 알 수 있다. 예를 들어 배추밭이 아래와 같이 구성되어 있으면 최소 5마리의 배추흰지렁이가 필요하다. 0은 배추가 심어져 있지 않은 땅이고, 1은 배추가 심어져 있는 땅을 나타낸다.

1 1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 1 1 0 0 0 1 1 1
0 0 0 0 1 0 0 1 1 1

 

입력

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트 케이스에 대해 첫째 줄에는 배추를 심은 배추밭의 가로길이 M(1 ≤ M ≤ 50)과 세로길이 N(1 ≤ N ≤ 50), 그리고 배추가 심어져 있는 위치의 개수 K(1 ≤ K ≤ 2500)이 주어진다. 그 다음 K줄에는 배추의 위치 X(0 ≤ X ≤ M-1), Y(0 ≤ Y ≤ N-1)가 주어진다. 두 배추의 위치가 같은 경우는 없다.

 

출력

각 테스트 케이스에 대해 필요한 최소의 배추흰지렁이 마리 수를 출력한다.

 

내 답안:
const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "input.txt";
let input = fs.readFileSync(filePath).toString().trim().split("\\n").map(x => x.split(" ").map(Number)) ;
input.shift() ;

class CountBug{
  cabbageSpot(arr, start){
    let [n,m,k] = input[now] ; //n = x = 가로, m = y = 세로
    let complex = new Array(m).fill(0).map(_ => Array(n).fill(0)) ;
    for (let i = start+1 ; i <= start + k ; i++ ){
      let x = arr[i][0] ;
      let y = arr[i][1] ;
      complex[y][x] = 1 ; //  1은 배추가 있음
    }
    this.complex = complex ;
    this.n = n ;
    this.m = m ;
    this.k = k ;
    return k ;
  }

  move(x,y){
    let xM = [-1, 0, 0, 1] ;// 좌 위 아래 우
    let yM = [0, -1, 1, 0] ;
    for (let i = 0 ; i < 4 ; i++ ){
      let newX = x + xM[i] ;
      let newY = y + yM[i] ;
      if ((newX >= 0)&&(newX < this.n)&&(newY >= 0)&&(newY < this.m)){
        if (this.complex[newY][newX] == 1) {
          this.complex[newY][newX] = 2
          this.stack.push([newX, newY]) ;
        }
      }
    }
  }

  count(){
    let count = 0 ;
    for (let i = 0 ; i < this.m ; i++ ){
      for (let j = 0 ; j < this.n ; j++ ){
        if (this.complex[i][j] == 1 ){
          let stack = [[j,i]] ;
          this.stack = stack ;
          while (stack.length != 0 ){
            let [x,y] = stack.pop() ;
            this.move(x,y) ;
          }
          count++ ;
        }
      }
    }
    return count
  }
}

let countBug = new CountBug() ;
let now = 0 ;
while (now < input.length){
  let k = countBug.cabbageSpot(input,now)+1 ;
  console.log(countBug.count()) ;
  now += k ;
}

>> 함수를 여러개로 쪼개서 하다보니 중복되는 변수가 많아 class를 사용하여 정리
>> DFS를 사용하기
다른사람 답안 참고하여 작성한 내 답안:
const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "input.txt";
let input = fs.readFileSync(filePath).toString().trim().split("\\n").map(x => x.split(" ").map(Number)) ;
input.shift() ;

class CountBug{
  cabbageSpot(arr, start){
    let [n,m,k] = input[now] ; //n = x = 가로, m = y = 세로
    let complex = new Array(m).fill(0).map(_ => Array(n).fill(0)) ;
    for (let i = start+1 ; i <= start + k ; i++ ){
      let x = arr[i][0] ;
      let y = arr[i][1] ;
      complex[y][x] = 1 ; //  1은 배추가 있음
    }
    this.complex = complex ;
    this.n = n ;
    this.m = m ;
    this.k = k ;
    return k ;
  }

  move(x,y){
    if ((x < 0)||(x >= this.n)||(y < 0)||(y >= this.m)) return false;
    if (this.complex[y][x] == 1) {
      this.complex[y][x] = 2
      this.move(x-1,y);
      this.move(x+1,y);
      this.move(x,y-1);
      this.move(x,y+1);
      return true
    } else return false;
  }

  count(){
    let count = 0 ;
    for (let i = 0 ; i < this.m ; i++ ){
      for (let j = 0 ; j < this.n ; j++ ){
        if (this.move(j,i) == true ){
            count++
        }
      }
    }
    return count
  }
}

const countBug = new CountBug() ;
let now = 0 ;
let answer = "" ;
while (now < input.length){
  let k = countBug.cabbageSpot(input,now)+1 ;
  answer += `${countBug.count()}\\n` ;
  now += k ;
}

console.log(answer.trim())
>> 재귀 이용

'백준' 카테고리의 다른 글

[실버] 색종이 만들기 (2630번)_JS  (0) 2022.12.19
[실버] 최소 힙 (1927번)_JS  (0) 2022.12.19
[실버] 2×n 타일링 (11726번)_JS  (0) 2022.12.19
[실버] ATM (11399번)_JS  (0) 2022.12.19
[실버] 1, 2, 3 더하기 (9095번)_JS  (0) 2022.12.19