구슬집어넣기
철수의 동생이 다니는 학교에서는 ‘구슬 집어넣기 게임’ 선풍적인 인기를 끌고 있다. 철수 동생은 반 친구들과 이 게임의 성적을 놓고 경쟁을 하고 있다.
어느 날, 철수의 동생이 시무룩한 얼굴을 하고 집에 들어왔다. 친구들보다 좋은 성적을 내지 못했다고 우울했던 것이다. 그래서 철수는 동생을 위해 게임에서 최고 성적을 내는 방법을 알려주는 프로그램을 만들기로 했다.
게임은 다음 룰에 의해 진행된다.
1.게임판에는 빨간구슬, 파란구슬, 벽, 그리고 목표구멍이 있다.
2. 플레이어는 총 10회 게임판을 기울일 수 있다. (방향 : 상하좌우)
3. 플레이어가 게임판을 기울이게 되면 해당 방향으로 빨간구슬과 파란구슬이 한 칸 이동한다.
4. 이동방향에 벽이 있는 구슬은 움직일 수 없다.
5. 이동 시 빨간 구슬과 파란 구슬이 같은 위치로 움직여 부딪히는 경우 구슬이 깨지므로, 게임 실패다.
6. 파란구슬이 목표구멍으로 들어가는 것은 게임 실패다.
7. 기울임 횟수가 10회를 넘어서면 게임 실패다.
8. 빨간 구슬이 목표구멍으로 들어가는 것이 이 게임의 목표이다.
9. 적은 횟수를 기울여 해결할수록 많은 높은 점수를 얻을 수 있다.
기본적으로 게임판의 가장자리는 구슬이 게임판 밖으로 빠져나가지 못하도록 벽으로 둘러쌓여 있다.
철수는 우선 이 게임에서 문제를 해결할 수 있는 가장 적은 횟수를 알고 싶다. 이를 출력하는 프로그램을 작성하시오.
입력
첫 번째 줄에 테스트 케이스 개수 T(1≤T≤10)가 주어진다.
이후부터 T개의 테스트 케이스 셋트가 주어진다.
셋트의 첫 번째 줄에는 게임판의 행(R)과 열(C)이 순서대로 주어진다. (3<=R,C<=15)
셋트의 두 번째 줄부터 게임판의 행만큼 게임판의 상황이 주어진다.
(B – 파란구슬, R – 빨간구슬, . – 이동가능지역, # - 벽, H-목표구멍)
출력
T줄에 걸쳐 각 테스트 케이스의 게임성공 최단 기울임 횟수를 출력하게 된다.
게임해결이 불가능한 경우 -1을 출력한다.
입력 예시
2
6 15
###############
#..#R#..B.....#
#..#.#.H......#
#....#.#......#
#.............#
###############
6 15
###############
#..#R#.B......#
#..#.#.H......#
#....#.#......#
#.............#
###############
출력 예시
8
9
#include <stdio.h> #define MAX 100 int T, R, C; int dir[4][2] = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } }; char board[MAX][MAX]; int answer[MAX]; typedef struct QUEUE { int rx, ry; int bx, by; int time; }QUEUE; QUEUE Q[MAX*MAX]; int wp, rp; int visited[20][20][20][20]; void push_queue(QUEUE t) { Q[wp++] = t; } QUEUE pop_queue() { return Q[rp++]; } int solution() { QUEUE tmp; while (1) { if (wp <= rp) break; tmp = pop_queue(); if (tmp.time >= 10) break; for (int i = 0; i < 4; i++) { int nextRX = tmp.rx + dir[i][0]; int nextRY = tmp.ry + dir[i][1]; int nextBX = tmp.bx + dir[i][0]; int nextBY = tmp.by + dir[i][1]; int nextT = tmp.time + 1; //printf("Rx %d Ry %d Bx %d By %d\n", nextRX, nextRY, nextBX, nextBY); if (board[nextBX][nextBY] == '#') { nextBX = tmp.bx; nextBY = tmp.by; } if (board[nextRX][nextRY] == '#') { nextRX = tmp.rx; nextRY = tmp.ry; } if ((nextRX == nextBX) && (nextRY == nextBY)) continue; if (visited[nextBX][nextBY][nextRX][nextRY] == 1) continue; if (board[nextBX][nextBY] == 'H') continue; if (board[nextRX][nextRY] == 'H') return nextT; else { QUEUE tmp2; tmp2.bx = nextBX, tmp2.by = nextBY; tmp2.rx = nextRX, tmp2.ry = nextRY; tmp2.time = nextT; visited[nextBX][nextBY][nextRX][nextRY] = 1; push_queue(tmp2); } } } return -1; } void input_data() { scanf("%d", &T); for (int k = 0; k < T; k++) { QUEUE tmp; tmp.time = 0; wp = rp = 0; scanf("%d %d", &R, &C); for (int i = 1; i <= R; i++) { getchar(); for (int j = 1; j <= C; j++) { scanf("%c", &board[i][j]); if (board[i][j] == 'R') { tmp.rx = i; tmp.ry = j; continue; } if (board[i][j] == 'B') { tmp.bx = i; tmp.by = j; continue; } } } for (int i = 0; i < sizeof(visited); i++) ((char*)visited)[i] = 0; push_queue(tmp); visited[tmp.bx][tmp.by][tmp.rx][tmp.ry] = 1; answer[k] = solution(); } /*for (int i = 1; i <= R; i++) { printf("\n"); for (int j = 1; j <= C; j++) { printf("%c", board[i][j]); } }*/ } int main(void) { // 여기서부터작성 input_data(); for (int i = 0; i < T; i++) printf("%d\n", answer[i]); return 0; }
댓글
댓글 쓰기