와이유스토리

[시뮬레이션] 프로그래머스 퍼즐 조각 채우기 C++ 본문

코딩테스트/시뮬레이션

[시뮬레이션] 프로그래머스 퍼즐 조각 채우기 C++

유(YOO) 2023. 3. 28. 21:59

 

https://school.programmers.co.kr/learn/courses/30/lessons/84021

#include <vector>
#include <queue>

using namespace std;

int N, answer;
int dx[4] = {1, 0, -1, 0}; // 우하좌상
int dy[4] = {0, 1, 0, -1};
vector<vector<int>> Board, Table;

bool check(int bx, int by, int tx, int ty, int k) { // k 회전 차이
    vector<vector<int>> B = Board;
    vector<vector<int>> T = Table;

    int cnt = 0;

    queue<vector<int>> q;
    q.push({bx, by, tx, ty});
    while(!q.empty()) {
        vector<int> v = q.front();
        q.pop();

        if (((v[2] < 0) || (v[3] < 0) || (v[2] >= N) || (v[3] >= N)) && ((v[0] < 0) || (v[1] < 0) || (v[0] >= N) || (v[1] >= N))) continue; // for문 바깥
        if ((v[2] < 0) || (v[3] < 0) || (v[2] >= N) || (v[3] >= N)) { // 경계 조심
            if (B[v[1]][v[0]] == 0) return false; // (B, T) = (0, 0) 퍼즐 칸 끼우기 불가능
            else continue; // (B, T) = (1, 0) 퍼즐 칸 끼우기 확인 안 해도 됨
        }
        if ((v[0] < 0) || (v[1] < 0) || (v[0] >= N) || (v[1] >= N)) {
            if (T[v[3]][v[2]] == 1) return false; // (B, T) = (1, 1) 퍼즐 칸 끼우기 불가능
            else continue; // (B, T) = (1, 0) 퍼즐 칸 끼우기 확인 안 해도 됨
        }

        if ((B[v[1]][v[0]] == 1) && (T[v[3]][v[2]] == 0)) continue; // (B, T) = (1, 0) 퍼즐 칸 끼우기 확인X
        if ((B[v[1]][v[0]] == 0) && (T[v[3]][v[2]] == 1)) { // (B, T) = (0, 1) 퍼즐 칸 끼우기 가능
            B[v[1]][v[0]] = 1;
            T[v[3]][v[2]] = 0;
            cnt++;
        }
        else return false; // (B, T) = (0, 0) or (1, 1) 퍼즐 칸 끼우기 불가능

        for(int i=0; i<4; i++) q.push({v[0] + dx[i], v[1] + dy[i], v[2] + dx[(i+k)%4], v[3] + dy[(i+k)%4]});
    }
    
    answer += cnt; // 퍼즐 한 개 칸 개수
    Board = B; // 퍼즐 끼우기
    Table = T;
    
    return true;
}

int solution(vector<vector<int>> game_board, vector<vector<int>> table) {
    N = game_board.size();
    Board = game_board;
    Table = table;
    
    for(int i=0; i<N; i++) { // DFS, 백트래킹 필요없음, O(N^4)=50^4=6250000
        for(int j=0; j<N; j++) { // 퍼즐 선택(기준)
            if (Table[i][j] == 1) { 
                for(int p=0; p<N; p++) {
                    for(int q=0; q<N; q++) {
                        if (Board[p][q] == 0) { // 보드 확인(회전 시계 방향 90도, 180도, 270도)
                            for(int k=0; k<4; k++) { // 상우하좌, 좌상우하, 하좌상우, 우하좌상
                                if (check(q, p, j, i, k)) continue;
                            }
                        }
                    }
                }
            }
        }
    }

    return answer;
}

 

#include <vector>
#include <queue>

using namespace std;

int N, answer;
int bdx[4] = {1, 0, -1, 0}; // 우하좌상
int bdy[4] = {0, 1, 0, -1};
int tdx[4] = {1, 0, -1, 0};
int tdy[4] = {0, 1, 0, -1};
vector<vector<int>> Board, Table;

bool check(int bx, int by, int tx, int ty) {
    vector<vector<int>> B = Board;
    vector<vector<int>> T = Table;

    int cnt = 0;

    queue<vector<int>> q;
    q.push({bx, by, tx, ty});
    while(!q.empty()) {
        vector<int> v = q.front();
        q.pop();

        if (((v[2] < 0) || (v[3] < 0) || (v[2] >= N) || (v[3] >= N)) && ((v[0] < 0) || (v[1] < 0) || (v[0] >= N) || (v[1] >= N))) continue; // for문 바깥
        if ((v[2] < 0) || (v[3] < 0) || (v[2] >= N) || (v[3] >= N)) {
            if (B[v[1]][v[0]] == 0) return false; // (B, T) = (0, 0) 퍼즐 칸 끼우기 불가능
            else continue; // (B, T) = (1, 0) 퍼즐 칸 끼우기 확인X
        }
        if ((v[0] < 0) || (v[1] < 0) || (v[0] >= N) || (v[1] >= N)) {
            if (T[v[3]][v[2]] == 1) return false; // (B, T) = (1, 1) 퍼즐 칸 끼우기 불가능
            else continue; // (B, T) = (1, 0) 퍼즐 칸 끼우기 확인X
        }

        if ((B[v[1]][v[0]] == 1) && (T[v[3]][v[2]] == 0)) continue; // (B, T) = (1, 0) 퍼즐 칸 끼우기 확인X
        if ((B[v[1]][v[0]] == 0) && (T[v[3]][v[2]] == 1)) { // (B, T) = (0, 1) 퍼즐 칸 끼우기 가능
            B[v[1]][v[0]] = 1;
            T[v[3]][v[2]] = 0;
            cnt++;
        }
        else return false; // (B, T) = (0, 0) or (1, 1) 퍼즐 칸 끼우기 불가능

        for(int i=0; i<4; i++) q.push({v[0] + bdx[i], v[1] + bdy[i], v[2] + tdx[i], v[3] + tdy[i]});
    }
    
    answer += cnt; // 퍼즐 한 개 칸 개수
    Board = B; // 퍼즐 끼우기
    Table = T;
    
    return true;
}

void rotate() { // 시계 방향
    int tempX = tdx[3];
    int tempY = tdy[3];
    for(int i=2; i>=0; i--) { // 뒤에서부터
        tdx[i+1] = tdx[i];
        tdy[i+1] = tdy[i];
    }
    tdx[0] = tempX;
    tdy[0] = tempY;
}

int solution(vector<vector<int>> game_board, vector<vector<int>> table) {
    N = game_board.size();
    Board = game_board;
    Table = table;
    
    for(int i=0; i<N; i++) { // DFS, 백트래킹 필요없음, O(N^4)=50^4=6250000
        for(int j=0; j<N; j++) { // 퍼즐 선택(기준)
            if (Table[i][j] == 1) { 
                for(int p=0; p<N; p++) {
                    for(int q=0; q<N; q++) {
                        if (Board[p][q] == 0) { // 보드 확인(회전 시계 방향 90도, 180도, 270도)
                            for(int k=0; k<4; k++) {
                                rotate(); // 상우하좌, 좌상우하, 하좌상우, 우하좌상
                                if (check(q, p, j, i)) continue;
                            }
                        }
                    }
                }
            }
        }
    }

    return answer;
}
#include <vector>
#include <queue>

using namespace std;

int N, answer;
int bdx[4] = {1, 0, -1, 0}; // 우하좌상
int bdy[4] = {0, 1, 0, -1};
int tdx[4] = {0, -1, 0, 1}; // 하좌상우
int tdy[4] = {1, 0, -1, 0};
vector<vector<int>> Board, Table;

bool check(int tx, int ty, int bx, int by) {
    vector<vector<int>> B = Board;
    vector<vector<int>> T = Table;

    int cnt = 0;

    queue<vector<int>> q;
    q.push({bx, by, tx, ty});
    while(!q.empty()) {
        vector<int> v = q.front();
        q.pop();

        if (((v[2] < 0) || (v[3] < 0) || (v[2] >= N) || (v[3] >= N)) && ((v[0] < 0) || (v[1] < 0) || (v[0] >= N) || (v[1] >= N))) continue; // for문 바깥
        if ((v[2] < 0) || (v[3] < 0) || (v[2] >= N) || (v[3] >= N)) {
            if (B[v[1]][v[0]] == 0) return false; // (B, T) = (0, 0) 퍼즐 칸 끼우기 불가능
            else continue; // (B, T) = (1, 0) 퍼즐 칸 끼우기 확인X
        }
        if ((v[0] < 0) || (v[1] < 0) || (v[0] >= N) || (v[1] >= N)) {
            if (T[v[3]][v[2]] == 1) return false; // (B, T) = (1, 1) 퍼즐 칸 끼우기 불가능
            else continue; // (B, T) = (1, 0) 퍼즐 칸 끼우기 확인X
        }

        if ((B[v[1]][v[0]] == 1) && (T[v[3]][v[2]] == 0)) continue; // (B, T) = (1, 0) 퍼즐 칸 끼우기 확인X
        if ((B[v[1]][v[0]] == 0) && (T[v[3]][v[2]] == 1)) { // (B, T) = (0, 1) 퍼즐 칸 끼우기 가능
            B[v[1]][v[0]] = 1;
            T[v[3]][v[2]] = 0;
            cnt++;
        }
        else return false; // (B, T) = (0, 0) or (1, 1) 퍼즐 칸 끼우기 불가능

        for(int i=0; i<4; i++) q.push({v[0] + bdx[i], v[1] + bdy[i], v[2] + tdx[i], v[3] + tdy[i]});
    }
    
    answer += cnt; // 퍼즐 한 개 칸 개수
    Board = B; // 퍼즐 끼우기
    Table = T;
    
    return true;
}

void rotate() { // 시계 방향
    int tempX = tdx[3];
    int tempY = tdy[3];
    for(int i=2; i>=0; i--) { // 뒤에서부터
        tdx[i+1] = tdx[i];
        tdy[i+1] = tdy[i];
    }
    tdx[0] = tempX;
    tdy[0] = tempY;
}

int solution(vector<vector<int>> game_board, vector<vector<int>> table) {
    N = game_board.size();
    Board = game_board;
    Table = table;
    
    for(int i=0; i<N; i++) { // DFS, 백트래킹 필요없음, O(N^4)=50^4=6250000
        for(int j=0; j<N; j++) { // 퍼즐 선택(기준)
            if (Board[i][j] == 0) { 
                for(int p=0; p<N; p++) {
                    for(int q=0; q<N; q++) {
                        if (Table[p][q] == 1) { // 보드 확인(회전 시계 방향 90도, 180도, 270도)
                            rotate(); // 우하좌상
                            if (check(q, p, j, i)) continue;

                            rotate(); // 상우하좌
                            if (check(q, p, j, i)) continue;

                            rotate(); // 좌상우하
                            if (check(q, p, j, i)) continue;

                            rotate(); // 하좌상우
                            if (check(q, p, j, i)) continue;
                        }
                    }
                }
            }
        }
    }

    return answer;
}
Comments