반응형
www.acmicpc.net/workbook/view/1152 (A형 문제집)
4방향으로 명령어대로 움직이면 되는 시뮬레이션 문제이다.
아래와 같은 주사위의 모양이 되도록,
6면체를 가지는 구조체 DICE를 만들자.
typedef struct st
{
int up;
int left; int top; int right;
int down;
int bottom;
}DICE;
DICE dice; /* map을 움직이는 dice는 전역으로 선언 */
최대한 그림과 비슷하게 모양을 만들어 두면, 디버깅할 때 편하다.
input 함수로 MAP과 command를 저장해두고, move 동/서/남/북을 만들자.
moveEast의 경우는 아래와 같다.
void moveEast()
{
int tmp[6] = { dice.up, dice.left, dice.top, dice.right, dice.down, dice.bottom };
dice.top = tmp[1];
dice.right = tmp[2];
dice.bottom = tmp[3];
dice.left = tmp[5];
}
dice의 6방향이 왜 저렇게 바뀌는지는 실제로 그려보면 된다.
다른 방향 함수는 최종 코드를 참고하자.
move 함수 이후에는 실제로 움직이도록 dr, dc를 선언하자.
dr, dc는 동 = 1, 서 = 2, 북 = 3, 남 = 4 가 되도록 만들면 편하다.
/* dummy, 동, 서, 남, 북 */
int dr[] = { 0, 0, 0, -1, 1 };
int dc[] = { 0, 1, -1, 0, 0 };
마찬가지로 move 4종류 함수를 1, 2, 3, 4와 mapping이 되도록 포인터를 선언해두면 바로 함수를 호출할 수 있다.
void(*MOVE[6])(void);
void moveEast();
...
int main(void)
{
input();
MOVE[1] = moveEast;
MOVE[2] = moveWest;
MOVE[3] = moveNorth;
MOVE[4] = moveSouth;
...
return 0;
}
함수 포인터를 잘 모른다면 if else를 이용해서 move를 실행하자.
( if(cmd == 1) moveEast(); )
K개의 command를 실행해주면 되는데, 이때 주사위가 벽을 넘어서는지에 대한 경계조건을 추가하면 된다.
최종 코드는 아래와 같다.
#include <stdio.h>
#define MAX (20+5)
int N, M, X, Y, K;
int MAP[MAX][MAX];
int command[1000 + 50];
typedef struct st
{
int up;
int left; int top; int right;
int down;
int bottom;
}DICE;
DICE dice;
void(*MOVE[6])(void);
void moveEast()
{
int tmp[6] = { dice.up, dice.left, dice.top, dice.right, dice.down, dice.bottom };
dice.top = tmp[1];
dice.right = tmp[2];
dice.bottom = tmp[3];
dice.left = tmp[5];
}
void moveWest()
{
int tmp[6] = { dice.up, dice.left, dice.top, dice.right, dice.down, dice.bottom };
dice.top = tmp[3];
dice.right = tmp[5];
dice.bottom = tmp[1];
dice.left = tmp[2];
}
void moveNorth()
{
int tmp[6] = { dice.up, dice.left, dice.top, dice.right, dice.down, dice.bottom };
dice.up = tmp[2];
dice.top = tmp[4];
dice.down = tmp[5];
dice.bottom = tmp[0];
}
void moveSouth()
{
int tmp[6] = { dice.up, dice.left, dice.top, dice.right, dice.down, dice.bottom };
dice.up = tmp[5];
dice.top = tmp[0];
dice.down = tmp[2];
dice.bottom = tmp[4];
}
void input()
{
scanf("%d %d %d %d %d", &N, &M, &X, &Y, &K);
for (int r = 0; r < N; r++)
for (int c = 0; c < M; c++)
scanf("%d", &MAP[r][c]);
for (int i = 0; i < K; i++) scanf("%d", &command[i]);
}
void output()
{
for (int r = 0; r < N; r++)
{
for (int c = 0; c < M; c++)
printf("%d ", MAP[r][c]);
putchar('\n');
}
putchar('\n');
for (int i = 0; i < K; i++) printf("%d ", command[i]);
putchar('\n');
}
void outputDice()
{
printf(" %d\n", dice.up);
printf("%d %d %d\n", dice.left, dice.top, dice.right);
printf(" %d\n", dice.down);
printf(" %d\n", dice.bottom);
putchar('\n');
}
int dr[] = { 0, 0, 0, -1, 1 };
int dc[] = { 0, 1, -1, 0, 0 };
int main(void)
{
input();
MOVE[1] = moveEast;
MOVE[2] = moveWest;
MOVE[3] = moveNorth;
MOVE[4] = moveSouth;
for (int i = 0; i < K; i++)
{
int cmd = command[i];
/* 바깥으로 나가게 되는 경우 */
if (X + dr[cmd] < 0 || X + dr[cmd] > N - 1
|| Y + dc[cmd] < 0 || Y + dc[cmd] > M - 1) continue;
X = X + dr[cmd];
Y = Y + dc[cmd];
MOVE[cmd]();
/* 이동한 칸이 0이면, 주사위의 바닥면의 수가 복사 */
if (MAP[X][Y] == 0) MAP[X][Y] = dice.bottom;
else /* 0이 아니면, 칸에 쓰여진 수가 바닥면으로 복사 */
{
dice.bottom = MAP[X][Y];
MAP[X][Y] = 0;
}
printf("%d\n", dice.top);
}
return 0;
}
A형의 경우 tc가 여러 개이므로 실제 시험에서는 main 코드는 다음과 같은 형식을 따른다.
int main(void)
{
int T;
scanf("%d", &T);
MOVE[1] = moveEast;
MOVE[2] = moveWest;
MOVE[3] = moveNorth;
MOVE[4] = moveSouth;
for (int tc = 1; tc <= T; tc++)
{
input();
for (int i = 0; i < K; i++)
{
...
}
printf("#%d %d\n", tc, dice.top);
}
return 0;
}
반응형
'알고리즘 > [ADV] 삼성 SW 역량 테스트 A형' 카테고리의 다른 글
BOJ 14501 : 퇴사 (삼성 SW TEST A형) (0) | 2021.02.15 |
---|---|
BOJ 14500 : 테트로미노 (삼성 SW TEST A형) (0) | 2021.02.15 |
BOJ 13458 : 시험 감독 (삼성 SW TEST A형) (0) | 2021.02.15 |
BOJ 3190 : 뱀 (삼성 SW TEST A형) (0) | 2021.02.14 |
BOJ 12100 : 2048 Easy (삼성 SW TEST A형) (0) | 2021.02.07 |
댓글