블록 이동하기 (Java, 해결중)

박세건·2023년 10월 10일
0

알고리즘 문제 해결

목록 보기
30/50

"0"과 "1"로 이루어진 지도인 board가 주어질 때, 로봇이 (N, N) 위치까지 이동하는데 필요한 최소 시간을 return 하도록 solution 함수를 완성해주세요.

라고 주어졌기때문에 바로 BFS를 떠올렸다.

중요하게 생각해야될것들

  • 이동하는것과 회전하는데에 걸리는 시간이 각각 1초.
  • 회전할때에는 회전 하고자 하는 방향의 대각선 부분이 빈칸이여야한다.
  • 로봇의 범위중 하나라도 (N, N)에 도달한다면 종료.
  • 로봇이 현재 가로방향인지 세로방향인지 체크

두개의 좌표를 연결해서 이동시켜줘야한다는 점에서 robot이라는 구조체를 만들어주고 BFS에 구조체를 넣어서 이동시키는 방법을 생각했다.
이동뿐만아니라 회전하는 방법도 있기에 먼저 이동이 정상적으로 작동하는지를 확인하기위해서 이동 부분먼저 구현하였고 이동부분을 문제없이 진행이 되었다.
회전하는 부분에서 어려움을 느꼈고 작성한 코드는 정상적으로 작동하지 않았다.

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

using namespace std;

int dix[4] = { 0,0,1,-1 };
int diy[4] = { 1,-1,0,0 };
bool visited[2][111][111];  //[2]는 방향을 뜻함




struct Robot {
    int x = 0, y = 0, xx = 0, yy = 1;
    bool direction = false;   //false값은 가로를 뜻한다.

    void print() {
        cout << x << " " << y << " " << xx << " " << yy << endl << direction << endl;
    }
    //회전을 나타내기 위한 함수
    void leftUp() {
        if (direction == 0) {
            xx = x - 1;
            yy = y;
        }
        else {
            xx = x;
            yy = y + 1;
        }
        direction=!direction;
    }
    void leftDown() {
        if (direction == 0) {
            xx = x + 1;
            yy = y;
        }
        else {
            xx = x;
            yy = y - 1;

        }
        direction=!direction;
    }
    void rightUp() {
        if (direction == 0) {
            x = xx - 1;
            y = yy;
        }
        else {
            x = xx;
            y = yy + 1;
        }
        direction=!direction;
    }
    void rightDown() {
        if (direction == 0) {
            x = xx + 1;
            y = yy;
        }
        else {
            x = xx;
            y = yy - 1;
        }
        direction=!direction;
    }

};
bool robotMove(Robot rb, vector<vector<int>> board) {
    if (rb.x >= 0 && rb.x < board.size() &&
        rb.y >= 0 && rb.y < board.size() &&
        rb.xx >= 0 && rb.xx < board.size() &&
        rb.yy >= 0 && rb.yy < board.size()) {  //로봇이 맵안에 위치하고
        if (board[rb.x][rb.y] == 0 && board[rb.xx][rb.yy] == 0) {   //로봇이 빈칸에 위치한다면
            if (visited[rb.direction][rb.x][rb.y] == false) {   //이전에 방문한적이 없다면
                visited[rb.direction][rb.x][rb.y] = true;
                return true;
            }
        }
    }
    return false;
}

int solution(vector<vector<int>> board) {
    int answer = 0;
    Robot rb;
    queue<pair<Robot, int>> q;
    q.push({ rb,0 });
    visited[rb.direction][rb.x][rb.y] = true;
    while (q.size() > 0) {
        Robot rb = q.front().first;
        int cnt = q.front().second;
        q.pop();
        for (int i = 0; i < 4; i++) {
            Robot newRb;
            newRb.x = rb.x + dix[i];
            newRb.y = rb.y + diy[i];
            newRb.xx = rb.xx + dix[i];
            newRb.yy = rb.yy + diy[i];
            newRb.direction = rb.direction;
            if (robotMove(newRb, board) == true) {
                newRb.print();
                q.push({ newRb,cnt + 1 });
            }
        }
        Robot newRb;

        newRb = rb;
        newRb.leftUp();
        if (robotMove(newRb, board) == true) {
            if ((newRb.direction==0&&board[newRb.x - 1][newRb.y+1] == 0)||
                (newRb.direction==1&&board[newRb.x +1][newRb.y+1] == 0)) {
                newRb.print();
                q.push({ newRb,cnt + 1 });
            }
        }
        newRb = rb;
        newRb.leftDown();
        if (robotMove(newRb, board) == true) {
            if ((newRb.direction==0&&board[newRb.x +1][newRb.y+1] == 0)||
                (newRb.direction==1&&board[newRb.x + 1][newRb.y-1] == 0)) {
                newRb.print();
                q.push({ newRb,cnt + 1 });
            }

        }
        newRb = rb;
        newRb.rightUp();
        if (robotMove(newRb, board) == true) { 
            if ((newRb.direction==0&&board[newRb.x - 1][newRb.y] == 0)||
                (newRb.direction==1&&board[newRb.x ][newRb.y+1] == 0)) {
                
                newRb.print();
                q.push({ newRb,cnt + 1 });
            }
        }
        newRb = rb;
        newRb.rightDown();
        if (robotMove(newRb, board) == true) {
            if ((newRb.direction==0&&board[newRb.x +1][newRb.y] == 0)||
                (newRb.direction==1&&board[newRb.x ][newRb.y-1] == 0)) {
                newRb.print();
                q.push({ newRb,cnt + 1 });
            }

        }
        cout << "--------------------------" << endl;
    }
    return answer;
}
profile
멋있는 사람 - 일단 하자

0개의 댓글