Henu
개발냥발
Henu
전체 방문자
오늘
어제
  • 분류 전체보기 (411)
    • DevOps (52)
      • Kubernetes (19)
      • Docker (14)
      • AWS (3)
      • Nginx (4)
      • Linux (4)
      • ArgoCD (1)
      • CN (2)
      • NATS (0)
      • Git (5)
    • Back-End (30)
      • Django (18)
      • Spring (5)
      • JPA (1)
      • MSA (5)
    • CS (87)
      • SystemSoftware (20)
      • OS (25)
      • Computer Architecture (16)
      • Network (23)
      • Database (2)
    • Lang (21)
      • Java (9)
      • Python (4)
      • C# (8)
    • Life (12)
    • 블록체인 (2)
    • Algorithm (204)
      • BOJ (160)
      • 프로그래머스 (19)
      • LeetCode (4)
      • SWEA (1)
      • 알고리즘 문제 해결 전략 (8)
      • DS, algorithms (7)
      • Checkio (5)
    • IT (2)

블로그 메뉴

  • GitHub
  • 글쓰기
  • 관리자

공지사항

  • Free!

인기 글

태그

  • docker
  • Network
  • BFS
  • 다이나믹 프로그래밍
  • Kubernetes
  • 백트래킹
  • django
  • boj
  • 프로그래머스
  • DFS

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Henu

개발냥발

Algorithm/프로그래머스

[프로그래머스 level2] 프렌즈4블록 (C++)

2022. 2. 22. 17:40

카카오 코딩테스트 [1차] 문제

 

2차원 배열의 원소가 떨어지는걸 구현하는게 핵심인 구현 문제이다.

 

문제에서 구현할 부분이 확실하게 나눠져 있음을 확인했다.

  1. 2x2 블록을 모두 찾아서 지우기
  2. 지워진 블록 떨어뜨리기

 

2x2블록을 찾아서 삭제하는 부분이다.

bool deleteBoard(){
    int del = 0;
    
    for(int r = 0; r < N; r++){
        for(int c = 0; c < M; c++){
            if(!board_records[r][c]) continue;
            del += delete2x2(nboard[r][c], r, c);
        }
    }
    
    for(int r = 0; r < N; r++){
        for(int c = 0; c < M; c++){
            if(board_records[r][c] == 2){
                board_records[r][c] = 0;
                nboard[r][c] = 0;
            }
        }
    }
    
    if(!del) return false;
    else{
        answer += del;
        return true;
    }
}

첫 번째 이중 for문을 돌면서 2x2 블록을 삭제한다. 삭제하면서 몇 개의 블록을 삭제했는지 확인하기 위해서 del 변수에 더해준다.

두 번째 이중 for문을 돌면서 삭제된 부분을 삭제 처리한다.

만약 지워진 블럭이 없다면 false를 리턴하고, 있다면 답을 갱신하고 true를 리턴한다.

 

 

이제 공중에 뜬 블럭들을 아래로 내려주는 작업이 필요하다.

void fall(){
    
    for(int c = 0; c < M; c++){
        int r = N-1;
        int vr = -1;
        
        while(r >= 0){
            if(board_records[r][c] == 0){
                vr = r;
            }
            while(vr != -1 && r >= 0){
                r--;
                if(nboard[r][c]){
                    nboard[vr][c] = nboard[r][c];
                    nboard[r][c] = 0;
                    board_records[r][c] = 0;
                    r = vr;
                    vr = -1;
                }
            }
            r--;
        }
    }
    
    for(int r = 0; r < N; r++){
        for(int c = 0; c < M; c++){
            if(nboard[r][c]) board_records[r][c] = 1;
            else board_records[r][c] = 0;
        }
    }
}

0번째 열부터 M-1번재 열까지 순서대로 확인한다.

각 열에서는 N-1번째 행부터(가장 아래쪽 행) 0번째 행까지 확인한다.

중요한 부분은 행을 확인하는 부분이다.

  1. 아래에서부터 올라가면서 비워진 부분을 체크한다. 
  2. 비워진 부분이 체크되었고, 채워진 부분을 찾았다면(현재 위치) -> 비워진 부분에 현재 위치의 블럭을 옮겨주고, 현재 위치를 비워진 블럭으로 바꿔준다.
  3. 행이 끝날때까지 반복하고, 열이 끝날때까지 반복한다.

 

 

최종 코드

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int N, M;
int answer = 0;

// 타일이 있으면 1, 타일이 없으면 0
// 타일이 있는데 이미 점수를 얻었으면 2
int board_records[31][31];
int nboard[31][31];

int dr[4] = {0, 0, 1, 1};
int dc[4] = {0, 1, 0, 1};

int delete2x2(int shape, int r, int c){
    // 지워진 타일의 개수를 반환
    if(r+1 == N || c+1 == M) return 0;
    
    int ret = 0;
    if(nboard[r+1][c]   == shape && 
       nboard[r][c+1]   == shape && 
       nboard[r+1][c+1] == shape){
        
        for(int k = 0; k < 4; k++){
            int nr = r + dr[k];
            int nc = c + dc[k];
            if(board_records[nr][nc] == 1){
                board_records[nr][nc] = 2;
                ret++;
            }
        }
    }
    
    return ret;
}

bool deleteBoard(){
    int del = 0;
    
    for(int r = 0; r < N; r++){
        for(int c = 0; c < M; c++){
            if(!board_records[r][c]) continue;
            del += delete2x2(nboard[r][c], r, c);
        }
    }
    
    for(int r = 0; r < N; r++){
        for(int c = 0; c < M; c++){
            if(board_records[r][c] == 2){
                board_records[r][c] = 0;
                nboard[r][c] = 0;
            }
        }
    }
    
    if(!del) return false;
    else{
        answer += del;
        return true;
    }
}

void fall(){
    
    for(int c = 0; c < M; c++){
        int r = N-1;
        int vr = -1;
        
        while(r >= 0){
            if(board_records[r][c] == 0){
                vr = r;
            }
            while(vr != -1 && r >= 0){
                r--;
                if(nboard[r][c]){
                    nboard[vr][c] = nboard[r][c];
                    nboard[r][c] = 0;
                    board_records[r][c] = 0;
                    r = vr;
                    vr = -1;
                }
            }
            r--;
        }
    }
    
    for(int r = 0; r < N; r++){
        for(int c = 0; c < M; c++){
            if(nboard[r][c]) board_records[r][c] = 1;
            else board_records[r][c] = 0;
        }
    }
}

int solution(int m, int n, vector<string> board) {
    N = m;
    M = n;
    
    for(int r = 0; r < N; r++){
        for(int c = 0; c < M; c++){
            nboard[r][c] = board[r][c] - 'A' + 1;
            if(nboard[r][c]) board_records[r][c] = 1;
        }
    }
    
    while(deleteBoard()){
        fall();
    }
    
    return answer;
}

 

'Algorithm > 프로그래머스' 카테고리의 다른 글

[프로그래머스 level 3] 입국심사(C++)  (0) 2022.03.02
[프로그래머스 level 3] 추석 트래픽 (Python)  (2) 2022.02.28
[프로그래머스 level2] 피로도 (C++)  (0) 2022.02.22
[프로그래머스 level2] H-index (C++)  (0) 2022.02.22
[프로그래머스] 다리를 지나는 트럭(C++) level2  (0) 2022.01.27
    'Algorithm/프로그래머스' 카테고리의 다른 글
    • [프로그래머스 level 3] 입국심사(C++)
    • [프로그래머스 level 3] 추석 트래픽 (Python)
    • [프로그래머스 level2] 피로도 (C++)
    • [프로그래머스 level2] H-index (C++)

    티스토리툴바