문제 요약
1. N x M 크기의 보드가 있다.
2. 로봇청소기는 동 서 남 북 방향을 바라볼 수 있다.
3. 현재 로봇 청소기가 있는 칸이 청소되어 있지 않다면(즉 Board [i][j] 칸이 0이라면) 청소한다.
4. 동 서 남 북 방향에 인접해 있는 곳에 청소되어 있지 않은 칸이 있다면
a. 바라보는 방향 유지후 후진하고 (3) 번으로
b. 후진했을 때 1이 있다면 작동 중지
5. 동 서 남 북 방향에 인접해 있는 곳에 모두 청소되어 있다면
a. 반시계 방향으로 90도 회전
b. 현재 바라보고 있는 방향을 기준으로 앞쪽 칸이 청소되어 있지 않았다면 그쪽으로 전진
c. (3) 번으로 돌아간다.
아이디어
이번에 시뮬레이션 문제를 설계할 때는 그냥 이렇게 하면 되겠지식으로 설계한 것이 아니라 어떻게 하면 깔끔하게 모듈로 나눌 수 있는 지를 생각 했다.
먼저 크게 문제를 나누고 세세하게 들어갔다.
기본 틀
먼저 저번 문제에서 깨달음을 얻었던 do while문을 사용했다.
가장 먼저 현재 로봇청소기가 위치해 있는 곳은 청소해야 하므로 do while문을 써야겠다 생각했다.
끝나는 조건은 (2) 번 조건에서만 끝낼 수 있기 때문에 따로 bool 변수를 만들어야겠다 생각함. (bool isFine = false)
네 방향 조사
그러면 남은 네 방향을 확인해야 하니 dx [4], dy [4] 방향 변수를 선언한다.
for(int dir = 0; dir < 4; ++dir)과 같은 식으로 계산한다.
네 방향(동, 서, 남, 북)을 조사하며 청소되지 않은 곳이 있다면 (isClean = true)로 바꾸고 반복문 break
아니라면 isClean 은 처음 그 상태 그대로 False 일 테니 가만히 있는다
isClean이 True라면 3번 조건
isClean이 False 라면 2번 조건 실행
2번 조건
각 방향에 맞게 뒤로 후진한다
dir == 0이라면 북쪽을 보고 있기 때문에 남쪽으로 한 칸 (x + 1)
dir == 1이라면 동쪽을 보고 있기 때문에 서쪽으로 한 칸 (y - 1)
dir == 2 라면 남쪽을 보고 있기 때문에 북쪽으로 한 칸 (x - 1)
dir == 3이라면 서쪽을 보고 있기 때문에 동쪽으로 한 칸 (y + 1)
3번 조건
방향 회전 dir - 1을 해서 -1이면 3을 아니면 그냥 dir -1 값을
dir = (dir - 1) == -1 ? 3 : dir-1;
계산한 값을 가지고 다음 칸이 청소되어 있지 않은 0이라면 이동
코드
int n, m;
int x, y, dirs;
int board[51][51];
int ans = 0;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
bool isFine = false;
void three(){
dirs = (dirs-1) == -1 ? 3 : dirs-1;
int nx = x + dx[dirs];
int ny = y + dy[dirs];
if(board[nx][ny] == 0){
x = nx; y = ny;
}
}
void two(){
int nx = x,ny = y;
if(dirs == 0) ++nx;
else if(dirs == 1) --ny;
else if(dirs == 2) --nx;
else if(dirs == 3) ++ny;
if(board[nx][ny] == 1)isFine = true;
else{
x = nx; y = ny;
}
}
int main()
{
init();
cin >> n >> m;
cin >> x >> y >> dirs;
for(int i=0; i < n; ++i)
for(int j =0; j < m; ++j)
cin >> board[i][j];
do{
bool isClean = false;
if(!board[x][y]){//1번
board[x][y] = -1;
ans++;
}
for(int dir = 0; dir < 4; ++dir){
int nx = x + dx[dir];
int ny = y + dy[dir];
if(board[nx][ny] == 1 || board[nx][ny] == -1)continue;
if(board[nx][ny] == 0){ //3번
isClean = true;
break;
}
}
if(isClean)three();
else two();
}while(!isFine);
cout << ans;
return 0;
}
문제를 풀며
내가 생각하는 골드 5문제가 아니었다 조금 쉬웠다. 내가 성장한 건지 문제가 쉬웠던 건지는 모르겠다!!
암튼 내 힘으로 답지를 보지 않고 맞췄서 너무너무 기분이 좋다! 진짜 정말 기분이 좋다 어쨌든 성장했다는 거니깐 ㅎㅎ
요즘 시뮬레이션류의 문제를 풀 때마다 자존감이 낮아졌는데 한 문제 맞혔다고 자존감이 맥스를 찍어 버렸다.
그리고 저번 문제에서 얻은 do while문 아이디어를 바로 사용하게 돼서 행복하다.
지금 까지의 공부가 헛되지는 않은것 같다 0.01정도는 성장한것 같다
고민의 흔적