ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준 27982] 큐브 더미 [C++]
    개발 일기/문제 일기 2023. 6. 20. 15:39
    728x90

     

    문제 링크

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

     

    27982번: 큐브 더미

    $N \times N \times N$ 크기의 입체 공간이 있다. 공간 속 좌표는 $1 \leq i,j,k \leq N$을 만족하는 세 정수 $(i,j,k)$로 나타낸다. 공간 속에는 $M$개의 큐브들이 존재하며, 각 큐브는 정확히 하나씩의 좌표를

    www.acmicpc.net

     

    백준 문제를 오랜만에 풀어왔습니다. 이 문제는 풀어보면 정말 별 거 없는데 설명이 이해가 안 되게 쓰여있더라고요. 저도 그것 때문에 몇 번 틀렸습니다. 게다가 나와있는 문제 해설도 얼마 없어서 더 헤맸네요. 많은 분들께서 저와 같이 헤매실까봐 이렇게 해설을 작성하게 되었습니다.

     

    1. 문제

     

     우선 문제를 간단히 요약하자면, 

     

    N * N * N 크기의 공간에서 (i, j, k) 좌표에 큐브가 있을 때, (i ± 1, j ± 1, k ± 1) 위치에도 큐브가 있는 조건을 성립하는 큐브를 찾는 것입니다.

     

     입력은 처음에는 공간의 크기 N, 입력 테스트의 개수 M, 그리고 M 줄에 걸쳐 i j k가 들어옵니다. 그 i j k 위치에 큐브를 넣은 후 모두 검사해서 조건에 맞는 큐브의 개수를 찾으면 됩니다.

     

     

    2. 해설

     

     이 문제는 문제 설명 자체가 모호하지, 문제만 정확히 하면 아주 쉽습니다. 간단히 말해 M번 동안 좌표를 받고, 그곳에 큐브를 둔 후, 검사하면 됩니다. 게다가 이 조건도 보면 큐브가 일단 정사면체니까, 3 * 3 * 3이라고 가정할 때 큐브 자신의 위아래 양옆에 큐브가 있다면 조건을 만족한 겁니다.

     

     그림으로 대충 그려보자면

    큐브 더미 조건

    이렇습니다. 이정도면 이해가 되셨을까요?

     

    3. 풀이

    #include <iostream>
    using namespace std;
    
    int main(void){
      
      // i, j, k를 저장하기 위한 3차원 배열
      // 모두 false로 초기화
      bool arr[7][7][7] = {false, };
      
      // n과 m 선언 후 입력 받기
      int n, m;
      cin >> n >> m;
      
      // m의 횟수 만큼 i, j, k 좌표를 입력 받음
      // 그 좌표에 큐브를 넣는다는 의미로 true를 넣음
      for(int l = 0; l < m; l++){
        int i, j, k;
        cin >> i >> j >> k;
        
        arr[i][j][k] = true;
      }
      
      // 조건에 맞는 큐브 갯수, 0으로 초기화
      int ans = 0;
      
      // i부터 k까지 for문을 돌며
      for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
          for(int k = 1; k <= n; k++){
          
          	// 만약 그 위치에 큐브가 있다면
            if(arr[i][j][k]){
            	// 그 큐브 주위에 큐브가 있는지 확인
              if(arr[i+1][j][k] && arr[i-1][j][k] && arr[i][j+1][k] && arr[i][j-1][k] && arr[i][j][k+1] && arr[i][j][k-1]){
                ans++;
              }
            }
          }
        }
      }
      
      // 큐브 갯수 촐력
      cout << ans;
    }

     

     

     이 문제에서 어려웠던 점은 역시 1번은 문제 이해고, 2번은 and 식을 사용하는 것 같아요. 평소라면 대체로 한 개의 and만 사용하면 되지만, 이곳에서는 앞뒤와 양옆에 큐브가 존재한다는 사실이 모두 true여야 하다보니, 자연스레 if문이 길어질 수밖에 없어요. 물론 중첩 if문을 사용해도 됩니다. 양 옆에 존재하는 게 true라면 앞뒤로 존재하는지 확인하고, 존재한다면 앞뒤로 존재하는지 확인하고, 존재한다면 위아래로 있는지 확인합니다. 그게 모두 true 면 큐브의 갯수를 하나 더해주는 것이죠. 하지만 그만큼 if문을 작성해야 하고 그 과정에서 실수가 일어날 가능성을 배제할 수 없기에 많은 분들께서 &&로 엮는 방식을 사용하시는 것 같아요. 그래서 저도 이번에 그렇게 작성해봤습니다. 원래 가로로 긴 문장을 안 좋아하다보니어색하게만 느껴지네요!

    728x90
Designed by Tistory.