새소식

코딩테스트/코드트리

[코드트리 챌린지] 트로미노

  • -

[실력진단 테스트]

[문제]

https://www.codetree.ai/cote/13/problems/tromino?&utm_source=clipboard&utm_medium=text 

 

코드트리 | 코딩테스트 준비를 위한 알고리즘 정석

국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.

www.codetree.ai

[문제 풀이]

백준 테트로미노와 비슷한 문제이다.

처음 보면 1. 이차원 배열을 모두 방문할 것. 2. 해당 배열에서 테트리스의 위치의 숫자들의 합을 구할 것. 3. 블록은 돌아갈 수 있으니 4번 돌릴것 의 3단계로 구현이 되어야 한다고 생각할 수 있다.

하지만 일반적으로 여기서 3번의 경우에서 발목이 잡히기 쉬운데

블록을 돌리는 작업이 생각보다 수고롭다는 것을 실제로 구현을 해보면 알 수가 있다.

 

그러니 여기선 블록을 직접 돌리지 말고 사람이 돌려준 뒤에 해당 위치를 모두 배열로 만들어서 알려주도록 하자.

 

 

이와 같은 총 6가지의 경우가 블록을 돌렸을 때 나올 수 있는 경우이니 이를 벡터에 넣어주도록 하자.

//테트리스 => [6][3][2]
vector<vector<vector<int> > > tetris = {
    {{0,0},{1,0},{1,1}},
    {{0,0},{0,1},{1,1}},
    {{0,1},{1,0},{1,1}},
    {{0,0},{0,1},{1,0}},
    {{0,0},{0,1},{0,2}},
    {{0,0},{1,0},{2,0}}
};

 

그러면 위와 같은 3차원 배열이 나올 것이고 우리들은 이를 통해서 해당 문제를 보다 쉽게 접근을 할 수가 있다.

 

처음 말했던 1,2,3 구현에서 3의 구현이 완료가 되었으니 1을 구현해보면

for(int i = 0;i<n;i++){
    for(int j = 0;j<m;j++){
        //테트리스 종류.
        for(int k = 0;k<6;k++){
        	answer = max(answer, 테트리스 합을 구하는 함수);
        }
    }
}

 

이와 같이 구현이 되고 그러면 이제 테트리스의 합을 구하는 구현에 넘어가보도록 하자.

 

테트리스 합을 구하는 함수 또한 생각보다 어렵지 않은데

int maxCheck(int x, int y, int k){
    int score = 0;
    for(int i = 0;i<3;i++){
        int nextX = x + tetris[k][i][0];
        int nextY = y + tetris[k][i][1];
        //inRange 함수는 해당 숫자가 범위 안인지 확인하는 함수
        if(inRange(nextX,nextY) == false) {
            return -1;
        }
        score += boards[nextX][nextY];
    }
    return score;
}

 

bfs에서 for문을 이용했던것과 비슷하게 쉽게 구현이 가능하다.

주의해야 할 점은 inRange(nextX,nextY) == true일때만 더하게 만들면

 

이와 같은 경우에서 6 과 9를 더한 값을 구한채로 반환을 해줄 수 있다.

해당 문제에서는 모든 값이 양수이니 문제가 되지 않지만 만약 해당 문제에 음수가 섞인다면 이와 같은 경우로 오답이 나올 수 있으니 범위를 벗어나면 바로 반환을 해주도록 하자.

[회고]

처음에 블록 회전에서 어떻게 해야 될지를 몰라서 어려워 했는데 발상을 해보면 어렵지 않게 풀릴 수 있는 문제였다.

또한, 해당 문제에서는 블록 회전이 필요 없지만 블록 회전을 실제로 사용하는 문제도 있으니 연습해 주도록 하자.

[코드]

#include <iostream>
#include <algorithm>
#include <vector>
#include <algorithm>

using namespace std;

int n,m;
int boards[210][210];

//tetris가 할 수 있는 모든 경우.
//테트리스 => [6][3][2]
vector<vector<vector<int> > > tetris = {
    {{0,0},{1,0},{1,1}},
    {{0,0},{0,1},{1,1}},
    {{0,1},{1,0},{1,1}},
    {{0,0},{0,1},{1,0}},
    {{0,0},{0,1},{0,2}},
    {{0,0},{1,0},{2,0}}
};

bool inRange(int x, int y){
    if(x >= 0 && x < n && y >= 0 && y < m){
        return true;
    }
    return false;
}

int maxCheck(int x, int y, int k){
    int score = 0;
    for(int i = 0;i<3;i++){
        int nextX = x + tetris[k][i][0];
        int nextY = y + tetris[k][i][1];
        if(inRange(nextX,nextY) == false) {
            return -1;
        }
        score += boards[nextX][nextY];
    }
    return score;
}

int main() {
    cin>>n>>m;
    for(int i = 0;i<n;i++){
        for(int j = 0;j<m;j++){
            cin>>boards[i][j];
        }
    }

    int answer = 0;
    for(int i = 0;i<n;i++){
        for(int j = 0;j<m;j++){
            //테트리스 종류.
            for(int k = 0;k<6;k++){
                answer = max(answer, maxCheck(i,j,k));
            }
        }
    }
    cout<<answer<<endl;
    return 0;
}

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.