2020 KAKAO BLIND RECRUITMENT 문제 중 하나인
블록 이동하기 문제를 풀어봤습니다.
막힘없이 코드를 작성하긴 했지만,, 정말 오랜 시간이 걸렸기 때문에
이 문제를 풀면서 제 실력이 어느 수준인지 느낄 수 있었습니다.
움직일 수 있는 것은 문제에 주어졌듯이 2가지 형태입니다.
로봇 전체를 동서남북으로 움직이거나 // 둘 중 하나의 축을 기준으로 회전시키는 것입니다.
회전을 좀 더 간단하게 구현할 수 있었다면 좋았겠지만
딱히 방법이 떠오르지 않아 노가다로 조건을 주었습니다..
#include <string>
#include <vector>
#include <queue>
using namespace std;
struct robot{
int y,x,side,time;
/*
side : 0, 1, 2, 3 // N, E, S, W
*/
};
int N;
int mx[4] = {0,0,-1,1};
int my[4] = {1,-1,0,0};
bool visit[100][100][4];
vector<vector<int> > board;
int getY(int y, int side){return side==0?y-1:(side==1?y:(side==2?y+1:y));}
int getX(int x, int side){return side==0?x:(side==1?x+1:(side==2?x:x-1));}
// ccw true : ccw || ccw false : cw
bool canMove(int y, int x, int side, int ccw){
if(side==0){
if(ccw){
if(x-1>=0&&!board[y-1][x-1]&&!board[y][x-1]&&!visit[y][x][3]) return true;
}
else{
if(x+1<N&&!board[y-1][x+1]&&!board[y][x+1]&&!visit[y][x][1]) return true;
}
}
if(side==1){
if(ccw){
if(y-1>=0&&!board[y-1][x+1]&&!board[y-1][x]&&!visit[y][x][0]) return true;
}
else{
if(y+1<N&&!board[y+1][x+1]&&!board[y+1][x]&&!visit[y][x][2]) return true;
}
}
if(side==2){
if(ccw){
if(x+1<N&&!board[y+1][x+1]&&!board[y][x+1]&&!visit[y][x][1]) return true;
}
else{
if(x-1>=0&&!board[y+1][x-1]&&!board[y][x-1]&&!visit[y][x][3]) return true;
}
}
if(side==3){
if(ccw){
if(y+1<N&&!board[y+1][x-1]&&!board[y+1][x]&&!visit[y][x][2]) return true;
}
else{
if(y-1>=0&&!board[y-1][x-1]&&!board[y-1][x]&&!visit[y][x][0]) return true;
}
}
return false;
}
int solution(vector<vector<int>> arr) {
int answer = 0;
board = arr;
N = board.size();
queue<robot> q;
q.push({0,0,1,0});
while(!q.empty()){
int fy = q.front().y;
int fx = q.front().x;
int side = q.front().side;
int sy = getY(fy, side);
int sx = getX(fx, side);
int time = q.front().time;
q.pop();
if((fy==N-1 && fx==N-1)||(sy==N-1&&sx==N-1)){
answer = time;
break;
}
if(visit[fy][fx][side]) continue;
visit[fy][fx][side] = true;
// move E,W,S,N
for(int i = 0; i<4; i++){
int ffy = fy+my[i];
int ffx = fx+mx[i];
int ssy = sy+my[i];
int ssx = sx+mx[i];
if(!(ffy>=0&&ffy<N&&ffx>=0&&ffx<N&&!board[ffy][ffx])) continue;
if(!(ssy>=0&&ssy<N&&ssx>=0&&ssx<N&&!board[ssy][ssx])) continue;
if(visit[ffy][ffx][side]) continue;
q.push({ffy,ffx,side,time+1}); // use side var
}
// move one point
// based fy, fx
if(canMove(fy,fx,side,true)){
for(int i = 0; i<4; i++){
if(side == i) q.push({fy,fx,(i+3)%4,time+1});
}
}
if(canMove(fy,fx,side,false)){
for(int i = 0; i<4; i++){
if(side==i) q.push({fy,fx,(i+1)%4,time+1});
}
}
// based sy, sx
if(canMove(sy,sx,(side+2)%4,true)){
for(int i = 0; i<4; i++){
if((side+2)%4 == i) q.push({sy,sx,(i+3)%4,time+1});
}
}
if(canMove(sy,sx,(side+2)%4,false)){
for(int i = 0; i<4; i++){
if((side+2)%4 == i) q.push({sy,sx,(i+1)%4,time+1});
}
}
}
return answer;
}
'algorithm > programmers' 카테고리의 다른 글
Programmers 실패율 (0) | 2020.12.10 |
---|---|
Programmers 가사 검색 (0) | 2020.12.09 |
Programmers 디스크 컨트롤러 C++ (0) | 2020.08.20 |
Programmers 카펫 C++ (0) | 2020.07.03 |
Programmers 숫자 야구 C++ (0) | 2020.07.03 |