카테고리 없음
백준 14503번 로봇청소기.
pine tree root
2019. 4. 28. 20:16
왼쪽 오른쪽 방향 탐색할때 사용할 경우의 배열을 다 만들면서 하였다. 1개로 줄일수 있는 방법이 없을까 찾아봐야겠다.
#include
#include
#include
using namespace std;
typedef struct {
int position_x;
int position_y;
int dir;
}robot_cleaner;
enum {
UP,
RIGHT,
DOWN,
LEFT
}ROBOT_DIR;
int depth, width, result;
int robot_x, robot_y, robot_dir;
int Map[50][50];
int up_next_dir[4] = { 3,2,1,0 };
int up_dirx[4] = { -1,0,1,0};
int up_diry[4] = { 0,1,0,-1 };
int right_next_dir[4] = { 0,3,2,1 };
int right_dirx[4] = { 0,-1,0,1 };
int right_diry[4] = { -1,0,1,0 };
int down_next_dir[4] = { 1,0,3,2 };
int down_dirx[4] = { 1,0,-1,0 };
int down_diry[4] = { 0,-1,0,1 };
int left_next_dir[4] = { 2,1,0,3 };
int left_dirx[4] = { 0,1,0,-1 };
int left_diry[4] = { 1,0,-1,0 };
bool game_end;
queue q;
void Input() {
scanf("%d %d", &depth, &width);
scanf("%d %d %d", &robot_y, &robot_x, &robot_dir);
q.push({ robot_x, robot_y, robot_dir });
for (int i = 0; i < depth; i++) {
for (int j = 0; j < width; j++) {
scanf("%d", &Map[i][j]);
}
}
}
void back_left(int position_x, int position_y) {
position_x = position_x+1;
position_y = position_y;
if (Map[position_y][position_x] == 1 || position_x >= width) {
printf("%d", result);
return;
}
else {
q.push({ position_x, position_y, LEFT });
}
}
void back_down(int position_x, int position_y) {
position_x = position_x ;
position_y = position_y-1;
if (Map[position_y][position_x] == 1 || position_y <0) {
printf("%d", result);
return;
}
else {
q.push({ position_x, position_y, DOWN });
}
}
void back_right(int position_x, int position_y) {
position_x = position_x-1;
position_y = position_y;
if (Map[position_y][position_x] == 1 || position_x < 0) {
printf("%d", result);
return;
}
else {
q.push({ position_x, position_y, RIGHT });
}
}
void back_up(int position_x, int position_y) {
position_x = position_x;
position_y = position_y+1;
if (Map[position_y][position_x] == 1 || position_y >= depth) {
printf("%d", result);
return;
}
else {
q.push({ position_x, position_y, UP });
}
}
void search(int position_x, int position_y, int dirx[4], int diry[4], int flag, int next_dir[4]) {
for (int i = 0; i < 4; i++) {
int next_positionx = position_x + dirx[i];
int next_positiony = position_y + diry[i];
if (next_positionx < 0 || next_positiony < 0 || next_positionx >= width || next_positiony >= depth) continue;
if (Map[next_positiony][next_positionx] != 0) {
robot_dir = i + 1;
continue;
}
game_end = false;
q.push({ next_positionx, next_positiony, next_dir[i]});
break;
}
if (game_end) {
switch (flag)
{
case UP:
back_up(position_x, position_y);
break;
case RIGHT:
back_right(position_x, position_y);
break;
case DOWN:
back_down(position_x, position_y);
break;
case LEFT:
back_left(position_x, position_y);
break;
default:
break;
}
}
}
void Calc() {
while (!q.empty()) {
int position_x = q.front().position_x;
int position_y = q.front().position_y;
int robot_dir = q.front().dir;
game_end = true;
q.pop();
if (Map[position_y][position_x] == 0) {
Map[position_y][position_x] = 2;
result++;
}
switch (robot_dir)
{
case UP:
search(position_x, position_y, up_dirx, up_diry, 0, up_next_dir);
break;
case RIGHT:
search(position_x, position_y, right_dirx, right_diry, 1,right_next_dir);
break;
case DOWN:
search(position_x, position_y, down_dirx, down_diry, 2, down_next_dir);
break;
case LEFT:
search(position_x, position_y, left_dirx, left_diry,3, left_next_dir);
break;
default:
break;
}
}
}
void Solve() {
Input();
Calc();
}
int main(void) {
Solve();
return 0;
}
수정본:
UP일 경우 뒤로 가는 규칙 탐색하는 규칙을 찾아 추가해줘서 하나의 dir배열만 사용하게 수정을 해줬다. 하면서 자꾸 2번째 케이스가 28이 나왔는데 항상 청소하지 못하는 곳이라도 회전을 해야 하는데 그걸 신경 써주지 못했다. 문제 파악을 철저히 하자.
#include#include #include using namespace std; typedef struct { int position_x; int position_y; int dir; }robot_cleaner; enum ROBOT_DIR { UP, RIGHT, DOWN, LEFT }; enum ROBOT_DIR rd; int new_dirx[4] = {0, 1, 0, -1}; int new_diry[4] = {-1, 0,1,0}; int depth, width, result; int robot_x, robot_y, robot_dir; int Map[50][50]; bool game_end; queue q; void Input() { scanf("%d %d", &depth, &width); scanf("%d %d %d", &robot_y, &robot_x, &robot_dir); q.push({ robot_x, robot_y, robot_dir }); for (int i = 0; i < depth; i++) { for (int j = 0; j < width; j++) { scanf("%d", &Map[i][j]); } } } ROBOT_DIR turn_direction(ROBOT_DIR rd) { switch (rd) { case UP: return rd = LEFT; case RIGHT: return rd = UP; case DOWN: return rd = RIGHT; case LEFT: return rd = DOWN; default: break; } } ROBOT_DIR back_going(ROBOT_DIR rd) { switch (rd) { case UP: return rd = DOWN; case RIGHT: return rd = LEFT; case DOWN: return rd = UP; case LEFT: return rd = RIGHT; default: break; } } void search(int position_x, int position_y, ROBOT_DIR rd) { ROBOT_DIR next_directtion=rd; for (int i = 0; i < 4; i++) { next_directtion= turn_direction(next_directtion); int next_positionx = position_x + new_dirx[next_directtion]; int next_positiony = position_y + new_diry[next_directtion]; if (next_positionx < 0 || next_positiony < 0 || next_positionx >= width || next_positiony >= depth) continue; if (Map[next_positiony][next_positionx] != 0) continue; game_end = false; q.push({ next_positionx, next_positiony, next_directtion}); break; } if (game_end) { next_directtion = back_going(next_directtion); position_x = position_x + new_dirx[next_directtion]; position_y = position_y + new_diry[next_directtion]; if (Map[position_y][position_x] == 1 || position_x < 0 || position_y < 0|| position_x>=width || position_y>=depth) { printf("%d", result); return; } else { q.push({ position_x, position_y, rd}); } } } void Calc() { while (!q.empty()) { int position_x = q.front().position_x; int position_y = q.front().position_y; int robot_dir = q.front().dir; game_end = true; q.pop(); if (Map[position_y][position_x] == 0) { Map[position_y][position_x] = 2; result++; } switch (robot_dir) { case UP: search(position_x, position_y,UP); break; case RIGHT: search(position_x, position_y,RIGHT); break; case DOWN: search(position_x, position_y,DOWN); break; case LEFT: search(position_x, position_y,LEFT); break; default: break; } } } void Solve() { Input(); Calc(); } int main(void) { Solve(); return 0; }