본문 바로가기

프로그래머스/KAKAO 2020 BLIND RECRUITMENT

기둥과 보 설치

728x90

programmers.co.kr/learn/courses/30/lessons/60061

 

코딩테스트 연습 - 기둥과 보 설치

5 [[1,0,0,1],[1,1,1,1],[2,1,0,1],[2,2,1,1],[5,0,0,1],[5,1,0,1],[4,2,1,1],[3,2,1,1]] [[1,0,0],[1,1,1],[2,1,0],[2,2,1],[3,2,1],[4,2,1],[5,0,0],[5,1,0]] 5 [[0,0,0,1],[2,0,0,1],[4,0,0,1],[0,1,1,1],[1,1,1,1],[2,1,1,1],[3,1,1,1],[2,0,0,0],[1,1,1,0],[2,2,0,1]] [[

programmers.co.kr

#include <string>
#include <vector>
#include <iostream>
using namespace std;


bool checkgidoong(vector<vector<pair<bool,bool>>> &arr, int i, int j){
    if(j==0){return true;}
    if(i-1>=0){
    if(arr[i-1][j].second==true){return true;}
    }
    if(arr[i][j].second==true){return true;}
    if(j-1>=0){
    if(arr[i][j-1].first==true){return true;}
    }
    return false;
}

bool checkbo(vector<vector<pair<bool,bool>>> &arr, int i, int j){
    
    if(j-1>=0){
    if(arr[i][j-1].first==true){
        return true;
    }
    }
    
    if(j-1>=0 && i+1<arr.size()){
    if(arr[i+1][j-1].first==true){
        return true;
    }
    }
    
    if((i-1>=0)&&(i+1<arr.size())){
    if((arr[i-1][j].second==true)&&(arr[i+1][j].second==true)){
        return true;
    }
    }
    return false;
}


bool checkarr( vector<vector<pair<bool,bool>>> &arr,int n){
    for(int i=0; i<=n; i++){
         for(int j=0; j<=n; j++){
             if(arr[i][j].first == true){
                 if(checkgidoong(arr,i,j)==false){
                     return false;
                 }
             }
             if(arr[i][j].second ==true){ // 기둥과 보 같이 i,j위치에 있을 수 있으므로 else if가 아닌 if를 써준다
                 if(checkbo(arr,i,j)==false){
                     return false;
                 }
             }
         }
    }
    return true;
}

vector<vector<int>> solution(int n, vector<vector<int>> build_frame) {
    vector<vector<int>> answer;
    vector<vector<pair<bool,bool>>>arr(n+1,vector<pair<bool,bool>>(n+1,make_pair(false,false)));
    for(int i=0; i<build_frame.size(); i++){
        
           int x = build_frame[i][0];
           int y = build_frame[i][1];
           if(build_frame[i][3]==0){
               if(build_frame[i][2]==0){
                   if(y<n){
                   arr[x][y].first = false;
                   if(checkarr(arr,n)==false){arr[x][y].first = true;}
                   }
               }
               else{
                   if( y>0&&x<n){
                   arr[x][y].second = false;
                   if(checkarr(arr,n)==false){arr[x][y].second = true;}
                   }
               }
           }
           else{
                   if(build_frame[i][2]==0){
                   if(y<n){
                   arr[x][y].first = true;
                   if(checkarr(arr,n)==false){arr[x][y].first = false;}
                   }
                }
               else{
                    if( y>0&&x<n){
                   arr[x][y].second = true;
                   if(checkarr(arr,n)==false){arr[x][y].second = false;}
                    }
                }
           }
    }
    
    for(int i=0; i<=n; i++){
        for(int j=0; j<=n; j++){
            if(arr[i][j].first == true){
                vector<int>v;
                v.push_back(i);
                v.push_back(j);
                v.push_back(0);
                answer.push_back(v);
            }
            if(arr[i][j].second == true){
                 vector<int>v;
                v.push_back(i);
                v.push_back(j);
                v.push_back(1);
                answer.push_back(v);
            }
            
        }
    }
    
/*    for(int k=0; k<answer.size(); k++){
    for(int i=0; i<3; i++){
        cout<<answer[k][i]<<" ";
    }
     cout<<endl;    
    }*/
    
    
    
    
    return answer;
}

- 시뮬레이션 문제이다. 

- 조건만 파악하면 쉬운 문제인데 같은 좌표 (i,j)에서 기둥과 보 둘다 있는 경우를 생각해서 두경우 모두 조건이 만족하는지 체크를 해주어야 한다. -> 이부분에서 처음에 틀렸었음.

 

<JAVA>

import java.util.*;
class Solution {
    
    static int FLOOR = 1;
    static int GI = 2;
    static int BO =3;

    static int[][]bmap; // 기둥과 보가 같은 좌표 일때를 고려하여 기둥 배열과 보배열을 따로 만들어준다.
    static int[][]gmap;
    
    static int sz;
    
    public boolean cango(int x, int y){
        return x>=0 && x<=sz && y>=0 && y<=sz; 
    }
    
    
    public boolean checkBo(int x, int y, int[][]bmap, int[][]gmap){
        
        if(!cango(x,y+1)){return false;}
        if(x==0){return false;}
        if(cango(x-1,y) && gmap[x-1][y]==GI){ //왼기둥 확인
            return true;
   
   
         }
        else if(cango(x-1,y+1)&&gmap[x-1][y+1]==GI){//오른기둥 확인
             return true;
   
        }
        else if(cango(x,y-1)&&cango(x,y+1)&&bmap[x][y-1]==BO && bmap[x][y+1]==BO){ //양 쪽이 보
            return true;
       
            
        }
        
        return false;
    }
    
    public boolean checkGd(int x, int y, int[][]bmap, int[][]gmap,boolean mode){
    
        if(!cango(x+1,y)){  return false;}
        
        if(mode ==true && x==0){return true;}
        if(gmap[x][y]==FLOOR || bmap[x][y]==BO){ //바닥 혹은 보
        
            return true;
        }
        else if(cango(x,y-1) && bmap[x][y-1]==BO){ //보의 시작점이 왼쪽
  
            return true;
        }
        else if(cango(x-1,y) && gmap[x-1][y]==GI){ //아래가 기둥일때
       
            return true;
        }
         return false;
    
    }
        

    
    
    public int[][] solution(int n, int[][] build_frame) {
        int[][] answer;
        ArrayList<int[]>arr = new ArrayList<>();
        sz=n;
        bmap = new int[n+1][n+1];
        gmap = new int[n+1][n+1];
        for(int i=0; i<=n; i++){
            bmap[0][i]= FLOOR; 
            gmap[0][i]= FLOOR;
        }
        
        for(int i=0; i<build_frame.length; i++){
            
            int[] ip = build_frame[i];
            int y = ip[0];
            int x = ip[1];
            int a = ip[2];
            int b = ip[3];
            
            if(b==1){ //설치
                if(a==1){ //보설치
                    if(checkBo(x,y,bmap,gmap)){
                        bmap[x][y]=BO;
                    }
                }
                else{ //기둥설치
                     if(checkGd(x,y,bmap,gmap,false)){
                         gmap[x][y]=GI;
                     }
                }
          
            } 
            else{ //삭제
                  
                
                if(a==1){//보를 삭제 할때
                    int prev = bmap[x][y];
              
                    if(x==0){ bmap[x][y]=1;} //바닥이라면 1로(사실 보는 바닥에 있을리 없으므로 이부분 삭제해도됨) 
                    else{ bmap[x][y]=0;}  //아니라면 삭제
 
                    
                    for(int p=0; p<=n; p++){
                        boolean tg =false;
                        for(int q=0; q<=n; q++){
                            if(bmap[p][q]==BO){ //보가 있다면
                                if(!checkBo(p,q,bmap,gmap)){ //체크했을때 해당 보가 위치할 수 없으면 
                                     bmap[x][y]=prev; //원래대로 복구
                                    tg=true; //이중 for 문 나가기 위한 toggle 
                                     break; 
                                }
                                
                            }
                            if( gmap[p][q]==GI){ //기둥이 있다면
                                  if(!checkGd(p,q,bmap,gmap,true)){//체크했을때 해당 기둥이 위치할 수 없으면 
                                     bmap[x][y]=prev; //원래대로 복구
                                      tg=true;
                                     break;
                                }
                            }
                        }
                        if(tg)break;
                    }
                }
                else{ //기둥삭제 -> 보와 같이 해준다.
                    int prev = gmap[x][y];
              
                    if(x==0){ gmap[x][y]=1;} //바닥은 1로 
                    else{ gmap[x][y]=0;} 
          
                    
                    for(int p=0; p<=n; p++){
                        boolean tg =false;
                        for(int q=0; q<=n; q++){
                            if(bmap[p][q]==BO){
                                if(!checkBo(p,q,bmap,gmap)){
                                 
                                     gmap[x][y]=prev;
                                    tg=true;
                                     break;
                                }
                                
                            }
                           if( gmap[p][q]==GI){
                                  if(!checkGd(p,q,bmap,gmap,true)){
                                  
                                     gmap[x][y]=prev;
                                      tg=true;
                                     break;
                                }
                            }
                        }
                        if(tg)break;
                    }
                }
                
        
                //     print();
                }
           
            }
            
    
        
        for(int j=0; j<=n; j++){ //문제에서의 xy좌표 기준과 나의 xy 좌표 기준이 반대이기 때문에 반대로 출력을 해야한다
            for(int i=0; i<=n; i++){
                
              
                if(gmap[i][j]==GI){ //기둥이 0 이니까 먼저 넣어줘야함 (작은 수가 앞으로)
                    int[] a = new int[3];
                    a[0]=j;
                    a[1]=i;
                    a[2]=0;
                    arr.add(a);
                }
                
                  if(bmap[i][j]==BO){ //보라면
                    int[] a = new int[3];
                    a[0]=j;
                    a[1]=i;
                    a[2]=1;
                    arr.add(a);
                }
                
            }
        }
        
        answer = new int[arr.size()][3];
        for(int i=0; i<arr.size(); i++){
            answer[i] = arr.get(i);
        }
        
        return answer;
    }
}

- 기둥과 보가 같은지점에 잇을 때를 고려해서 현재 해당 지점에 위치해 있는지 알려주는 bmap과 gmap 이차원배열 두개를 사용해야 틀리지 않는다.

'프로그래머스 > KAKAO 2020 BLIND RECRUITMENT' 카테고리의 다른 글

외벽 점검  (0) 2021.02.21
블록이동하기  (0) 2021.02.19