본문 바로가기
알고리즘 풀이/프로그래머스

[프로그래머스] 기둥과 보 설치 - JAVA

by 2245 2023. 9. 20.

🔗 문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

👨🏻‍💻 풀이 및 코드

단순 구현 문제였습니다.

기둥과 보를 설치하는 조건이 여러 개여서, 설치하거나 삭제할 때 해당 조건을 만족하는 지를 체크하는 알고리즘을 구현하는 것이 관건이었습니다.

 

먼저, 헷갈리지 않게 기둥과 보 설치 유무를 체크하는 boolean[][] 배열을 각각 따로 만들어서 체크했습니다.

설치할 땐, checkPillar() 함수와 checkBeam() 함수를 각각 따로 만들어 주어진 조건을 만족하는지 체크했습니다.

삭제할 떈, 우선 삭제를 진행했다가 전체 구조물이 주어진 조건을 만족하는지 검사한 후 조건에 맞지 않는다면 다시 원상복구를 시켰습니다. 조건에 만족한다면 그대로 삭제를 진행시켰습니다.

 

최종 반환 값에서 전체 기둥과 보의 총 설치 갯수를 필요로 하기에 설치 및 삭제할 때 cnt 변수를 사용해 전체 갯수를 계산해주었습니다.

 

 

전체 코드

class Solution {
    boolean[][] pillar, beam;
    int n;
    
    public int[][] solution(int n, int[][] build_frame) {
        this.n = n;
        pillar = new boolean[n+1][n+1];     //기둥 설치 유무
        beam = new boolean[n+1][n+1];       //보 설치 유무
        int cnt = 0;    //설치된 기둥과 보의 총 갯수
        for(int[] build : build_frame) {
            int x = build[0];
            int y = build[1];
            int type = build[2];    //0은 기둥, 1은 보
            int action = build[3];  //0은 삭제, 1은 설치
            
            if(type == 0) {  
                if(action == 0) {   //삭제
                    pillar[x][y] = false;
                    if(!canDelete()) pillar[x][y] = true;
                    else cnt--;
                } else {
                    if(checkPillar(x, y)) {
                        pillar[x][y] = true;
                        cnt++;
                    }
                }
            } else {
                if(action == 0) {
                    beam[x][y] = false;
                    if(!canDelete()) beam[x][y] = true;
                    else cnt--;
                } else {
                    if(checkBeam(x, y)) {
                        beam[x][y] = true;
                        cnt++;
                    }
                }
            }
        }
        
        int[][] answer = new int[cnt][3];
        int idx = 0;
        for(int i=0; i<=n; i++) {
            for(int j=0; j<=n; j++) {
                if(pillar[i][j]) {
                    answer[idx][0] = i;
                    answer[idx][1] = j;
                    answer[idx][2] = 0;
                    idx++;
                }
                if(beam[i][j]) {
                    answer[idx][0] = i;
                    answer[idx][1] = j;
                    answer[idx][2] = 1;
                    idx++;
                }
            }
        }
        return answer;
    }
    
    //삭제 가능 여부
    boolean canDelete() {
        for(int i=0; i<=n; i++) {
            for(int j=0; j<=n; j++) {
                if(pillar[i][j]) {
                    if(!checkPillar(i, j)) return false;
                }
                if(beam[i][j]) {
                    if(!checkBeam(i, j)) return false;
                }
            }
        }
        
        return true;
    }
    
    //기둥 설치 가능 체크
    boolean checkPillar(int x, int y) {
        if(y==0) return true;   //바닥
        if(y>0 && pillar[x][y-1]) return true; //다른 기둥 위
        if(beam[x][y] || (x>0 && beam[x-1][y])) return true;    //보의 한쪽 끝 부분 위
        return false;
    }
    
    //보 설치 체크
    boolean checkBeam(int x, int y) {
        if(y>0 && (pillar[x][y-1] || pillar[x+1][y-1])) return true; //한 쪽 끝 부분이 기둥 위
        if(x>0 && beam[x-1][y] && beam[x+1][y]) return true; //다른 보와 동시에 연결
        return false;
    }
}