새소식

💻 Computer/🐘 Algorithm

[16236] 아기 상어 - C++

  • -


풀이

이번 글에서는 어떻게 구상하고 설계했는지 자세하게 적어 보려고 한다

 

1. 나에게 가까운 것을 찾아야 한다.

BFS를 사용할 수 있을 듯하다.

가까운 것이 여러 개 있다면 가장 위에 있는 것, 그중에서도 여러 개 있다면 가장 왼쪽의 것을 고르라 하니 

BFS를 돌고 for문을 사용해도 될 듯하다.

 

시간을 표시해줘야 하니 Dist라는 -1로 채워진 $ N \times N $ 배열을 만들어 줘야 한다.

 

2. 상어를 성장시켜야 한다.

baby라는 상어의 현재 크기를 담는 변수

growing이라는초기값은 0이고, 물고기를 먹을 때마다 증가시킨다.

 

만약 baby 변수와 값이 동일해진다면 baby증가, growing은 0으로 초기화

상어의 무게를 늘려주는 식으로 구상했다.

 

3. 종료 조건

무한 반복을 돌리며 더 이상 상어가 이동할 곳이 없을 때 시간을 출력하고 return 하는 식으로 구상함


코드

#include <bits/stdc++.h>

//불가능한 값 Max
#define Max 1000

using namespace std;
void init(){
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
}

int n, t = 0;

int board[22][22], dist[22][22];

int dx[4] = {0, 0, -1, 1};
int dy[4] = {1, -1, 0, 0};

queue<tuple<int, int, int>> q;

int baby = 2;
int growing = 0;

bool OOB(int nx, int ny){
  return nx < 0 || nx >= n || ny < 0 || ny >= n;
}

void distInit(int size){
  for(int i = 0; i < size; ++i)
    fill(dist[i], dist[i] + size, -1);
}

int main(){
  init();
  cin >> n;
  
  //dist를 -1로 초기화하는 함수
  distInit(n);
  
  //입력
  for(int i= 0; i < n; ++i){
    for(int j = 0; j < n; ++j){
      cin >> board[i][j];
      if(board[i][j] == 9){
      	//입력 받으며 시작 위치를 찾아냄
        q.push({i, j, 0});
        
        //시작부분의 시간은 0으로 변경
        dist[i][j] = 0;
      }
    }
  }

  while(1){
  	//BFS
    while(!q.empty()){
      int x, y, cnt; tie(x, y, cnt) = q.front(); q.pop();
      
      int nxtCnt = cnt + 1;
      for(int dir = 0; dir < 4; ++dir){
        int nx = x + dx[dir];
        int ny = y + dy[dir];
        if(OOB(nx, ny)) continue;
        if(dist[nx][ny] > -1 || board[nx][ny] > baby)continue;

        q.push({nx, ny, nxtCnt});
        //나와 동일한 크기의 물고기라면 불가능한 크기의 값으로 바꿔주고
        //나보다 작다면 nxtCnt를 넣어준다.
        dist[nx][ny] = (board[nx][ny] == baby ? Max : nxtCnt);
      }
    }
    
    //불가능한 값  MAX를 mins의 초기값으로 넣어준다.
    int mins = Max;
    
    //먹은 물고기의 위치를 넣어줄 변수 x, y
    int x, y;
    for(int i= 0; i < n; ++i){
      for(int j = 0; j < n; ++j){
        //전 시작위치 9는 0으로 바꿔준다.
        if(board[i][j] == 9) board[i][j] = 0;
        else if(board[i][j] > 0 && dist[i][j] != -1 && mins > dist[i][j]){
          mins = dist[i][j];
          x = i; y = j;
        }
      }
    }

	// mins가 변경 되었다면, 즉 물고기를 하나라도 먹었다면 실행
    if(mins != Max){
      t += dist[x][y];
      board[x][y] = 9;
      q.push({x, y, 0});
      if(++growing == baby){baby++;growing = 0;}
      distInit(n);
      dist[x][y] = 0;
    } else{
      cout << t << '\n';
      return 0;
    }
  }
  return 0;
}

글을 마치며

오랜만에 구현 && BFS 문제를 풀어 보았는데 예전보다 성장한 게 눈에 보여서 좋다.

처음 구현 문제를 풀 때는 어떻게 풀지 몰라 당황하고 그랬었는데, 많이 풀고 익숙해지니 늘긴 하는구나

근데 코드가 너무 더러운 것 같은데 이건 어떻게 해결해야 하지

'💻 Computer > 🐘 Algorithm' 카테고리의 다른 글

[2133] 타일 채우기 - C++  (0) 2023.06.29
[3015] 오아시스 재결합 - C++  (0) 2023.06.28
[10942] 팰린드롬? - C++  (0) 2023.06.27
[11057] 오르막 수 - C++  (0) 2023.06.26
[9465] 스티커 - C++  (0) 2023.06.26
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.