본문 바로가기
알고리즘/[ADV] 삼성 SW 역량 테스트 A형

BOJ 14503 : 로봇 청소기 (삼성 SW TEST A형)

by 피로물든딸기 2021. 2. 17.
반응형

삼성 A형 전체 링크

 

www.acmicpc.net/workbook/view/1152 (A형 문제집)

 

www.acmicpc.net/problem/14503

 

로봇 청소기와 같은 시뮬레이션은, 시키는 대로 구현하면 된다.

 

좌표 4방향, 북, 동, 남, 서는 문제에서 아래와 같이 정의되어있다.

/* 0 1 2 3 -> 북 동 남 서 */
int dr[] = { -1, 0, 1, 0 };
int dc[] = { 0, 1, 0, -1 };

 

방향 전환은 배열을 이용해서 간단히 할 수 있다.

int change[] = { 3, 0, 1, 2 };

북(0)에서 왼쪽으로 회전하면 서(3),

동(1)에서 왼쪽으로 회전하면 북(0),

...

 

으로 4방향에 대해서만 정의해주면 되므로 복잡하게 함수를 만들거나 if/else를 사용할 필요가 없다.

 

최종 코드에 로봇 청소기의 작동에 대해 주석을 추가하였다. 

#include <stdio.h>

#define MAX (50+5)

int N, M, R, C, D;
int MAP[MAX][MAX];

void input()
{
	scanf("%d %d %d %d %d", &N, &M, &R, &C, &D);

	for (int r = 0; r < N; r++)
		for (int c = 0; c < M; c++)
			scanf("%d", &MAP[r][c]);
}

int dr[] = { -1, 0, 1, 0 };
int dc[] = { 0, 1, 0, -1 };

int main(void)
{
	int flag, sum;
	int change[] = { 3, 0, 1, 2 };

	input();

	flag = 0;
	while (1)
	{
		MAP[R][C] = 2; /* 1. 현재 위치를 청소한다. */

		/* 2. 현재 위치에서 현재 방향을 기준으로 왼쪽방향부터 차례대로 탐색을 진행한다. */

		int tmpDir = change[D]; /* 왼쪽을 탐색하기 위한 방향과 좌표 설정. */
		int nr = R + dr[tmpDir]; 
		int	nc = C + dc[tmpDir];

		/* a. 왼쪽 방향에 아직 청소하지 않은 공간이 존재한다면,
		그 방향으로 회전한 다음 한 칸을 전진하고 */ 
		if (MAP[nr][nc] == 0) 
		{
			D = tmpDir;
			R = nr;
			C = nc;

			MAP[R][C] = 2; /* 1번부터 진행한다. */
		}
		else /* b. 왼쪽 방향에 청소할 공간이 없다면, 그 방향으로 회전하고 2번으로 돌아간다.*/
		{
			int i;
			for (i = 0; i < 4;i++)
			{
				// 회전
				D = tmpDir;
				//printf("%d\n", D);
				int nr = R + dr[D];
				int nc = C + dc[D];

				//회전한 방향이 청소할 수 있다면.
				if (MAP[nr][nc] == 0)
				{
					R = nr;
					C = nc;
					break;
				}

				tmpDir = change[D];
			}
			
			/* c. 네 방향 모두 청소가 이미 되어있거나 벽인 경우에는, 
			바라보는 방향을 유지한 채로 한 칸 후진을 하고 2번으로 돌아간다. */
			if (i == 4)
			{
				nr = R - dr[D]; /* 후진 */
				nc = C - dc[D];
				R = nr;
				C = nc;

				/* d. 네 방향 모두 청소가 이미 되어있거나 벽이면서, 
				뒤쪽 방향이 벽이라 후진도 할 수 없는 경우에는 작동을 멈춘다. */
				if (MAP[R][C] == 1) flag = 1;
			}

		}

		if (flag) break;
	}

	MAP[R][C] = 5;

	sum = 0;
	for (int r = 0; r < N; r++)
		for (int c = 0; c < M; c++) /* 청소한 칸을 count */
			if (MAP[r][c] == 2) sum++;

	printf("%d\n", sum);

	return 0;
}
반응형

댓글