[프로그래머스] 기둥과 보 설치 (Java)

nnm·2020년 5월 3일
1

프로그래머스 기둥과 보 설치

문제풀이

별다른 알고리즘을 요구하는 문제는 아니지만 구현이 까다로운 문제였다. 주어진 명령에 대한 유효성 체크를 하면 되는 것인데 잘풀리지않아서 한참을 헤매다 결국 다른 분의 풀이를 참고했다. 깔끔하게 이해되는 풀이였다.

  • 기둥과 보를 따로 관리한다.
    • 한 칸에 기둥과 보 둘 다 존재할 수 있기 때문이다.
    • 구현의 편의성
  • 데이터를 변형하기보다 주어진 형태에 맞춰서 생각해본다.
    • 주어진 명령어에 대해서 주어진 규칙을 만족하는지만 확인하면 되기 때문에 굳이 좌표평면에 대한 고민을 하지 않아도 된다.
    • 유효성 검사시 인덱스가 배열을 벗어나는 것을 대비하여 패딩만 준다.
  • 철거 명령에 대한 유효성 검사는 일단 철거하여 전체 건축물에 대한 검사를 수행한다.
  • 검사는 어떻게 하는가?
    • 1번 테스트케이스를 바탕으로 배열에 데이터가 어떻게 들어가는지 확인하고 그를 바탕으로 검사 코드를 작성하면된다.

구현코드

import java.util.*;

class Solution {
    
    static final int PILLAR = 0;
    static final int BEAM = 1;
    static final int DESTRUCT = 0;
    static final int CONSTRUCT = 1;
    
    boolean[][] pillars, beams; // 기둥, 보
    
    public int[][] solution(int n, int[][] build_frame) {
        int structureCount = 0;
        
        pillars = new boolean[n + 3][n + 3];
        beams = new boolean[n + 3][n + 3];
        
        for(int[] frame : build_frame){
            int x = frame[0] + 1;
            int y = frame[1] + 1;
            int structureType = frame[2];
            int commandType = frame[3];
            
            if(commandType == CONSTRUCT){
                if(structureType == PILLAR && canConstructPillar(x, y)){
                    pillars[x][y] = true;
                    structureCount++;
                }
                if(structureType == BEAM && canConstructBeam(x, y)){
                    beams[x][y] = true;
                    structureCount++;
                }
            } else if(commandType == DESTRUCT){
                if(structureType == PILLAR){
                    pillars[x][y] = false;
                } else if(structureType == BEAM){
                    beams[x][y] = false;
                }
 
                if(canDestruct(x, y, structureType, n)){
                    structureCount--;
                    continue;
                }
                
                if(structureType == PILLAR){
                    pillars[x][y] = true;
                } else if(structureType == BEAM){
                    beams[x][y] = true;
                }
            }
        }
            
            int index = 0;
            int[][] answer = new int[structureCount][3];
            
            for(int i = 1 ; i <= n + 1 ; ++i){
                for(int j = 1 ; j <= n + 1 ; ++j){
                    if(pillars[i][j]) answer[index++] = new int[]{i - 1, j - 1, PILLAR};
                    if(beams[i][j]) answer[index++] = new int[]{i - 1, j - 1, BEAM};
                }
            }
            return answer;
    }
    
    private boolean canConstructPillar(int x, int y){
        return y == 1 || pillars[x][y - 1] || beams[x][y] || beams[x - 1][y];
    }
    
    private boolean canConstructBeam(int x, int y){
        return pillars[x][y - 1] || pillars[x + 1][y - 1] || (beams[x - 1][y] && beams[x + 1][y]);
    }
    
    private boolean canDestruct(int x, int y, int structureType, int n){       
        for(int i = 1 ; i <= n + 1 ; ++i){
            for(int j = 1 ; j <= n + 1 ; ++j){
                if(pillars[i][j] && !canConstructPillar(i, j)){
                    return false;
                }
                if(beams[i][j] && !canConstructBeam(i, j)){
                    return false;
                }
            }
        }
        
        return true;
    }
}
profile
그냥 개발자

2개의 댓글

comment-user-thumbnail
2020년 5월 8일

안녕하세요. '다른 분의 풀이'의 다른 분입니다. ㅎㅎ 깔끔하게 이해되는 풀이라고 해주셔서 기분 좋아졌습니다. 감사합니다!

1개의 답글