관리 메뉴

공부 기록

백준 3709 레이저빔은 어디로 본문

코딩테스트/[BOJ] 문제 풀이

백준 3709 레이저빔은 어디로

_JAEJAE_ 2021. 8. 28. 16:27

https://www.acmicpc.net/problem/3709

 

3709번: 레이저빔은 어디로

레이저박스라는 게임은 정사각형  모양의 n x n 보드에서 진행한다. (체스판을 상상하면 된다) 레이저박스의 임의의 칸마다 우향우 거울이라는 장치가 설치되어 있고, 마지막으로 레이저 한개가

www.acmicpc.net

문제

레이저박스라는 게임은 정사각형  모양의 n x n 보드에서 진행한다. (체스판을 상상하면 된다) 레이저박스의 임의의 칸마다 우향우 거울이라는 장치가 설치되어 있고, 마지막으로 레이저 한개가 설치되어 있다. 레이저는 판의 끝에만 설치 될 수 있는데, 행의 맨 아래/맨 위, 열의 오른쪽 끝/왼쪽 끝에 설치 될 수 있다. 레이저에서 나온 빔은 그 행 혹은 열을 질러서 반대쪽을 비춘다.

게임은 우향우 거울을 임의의 칸마다 설치한 후, 레이저를 배치를 해 놓은 이후에 시작한다. 레이저를 켰을 때 나온 빔이 우향우 거울을 통과하면 진입한 방향과는 관계 없이 오른쪽으로 90도를 꺾어 다시 나아간다. 

레이저 빔이 마지막으로 어느 좌표를 향해 비춰지는지 구하라.

입력

첫 줄에는 테스트케이스의 총 개수가 주어진다.

테스트케이스의 첫 줄에는 보드의 크기 n(1 ≤ n ≤ 50)과 우향우 거울의 개수 r(1 ≤ r ≤ 50)이 주어진다.

이어지는 r개의 줄에는 우향우 거울이 배치된 좌표 x y가 주어진다.(좌표는 1부터 시작한다) 중복된 좌표는 있을 수 없고, 매 칸마다 최대 1개의 우향우 거울이 놓일 수 있다.

마지막 줄에는 레이저의 좌표가 주어진다. 레이저는 행과 열의 끝, 즉 판 밖에 위치해야 하므로 레이저의 좌표에는 0 혹은 n + 1이 포함된다. 

예를 들어, 2x2보드의 1행 맨 밑에서 위로 쏘아지는 레이저의 좌표는 (3, 1)로써 주어진다. 마찬가지로 6x6보드의 6열 왼쪽 끝에서 오른쪽 끝으로 쏘아지는 레이저의 좌표는 (6, 0)이 되겠다.

출력

매 테스트케이스마다 빔이 보드를 떠나는 좌표 X Y를 출력하라. 레이저의 좌표와 마찬가지로 빔은 보드 밖으로 떠나기에 좌표에는 0 혹은 n + 1이 포함된다. 

만약 빔이 보드 밖을 떠나지 않을 경우의 출력은 0 0이 된다.

예제 입력 1 

2

2 3

1 1

1 2

2 2

3 1

3 6

1 1

1 3

2 2

2 3

3 1

3 2

2 0

예제 출력 1 

2 0 0 2


[풀이 과정]

1. 

 


[소스 코드]

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAX = 55;

int n, r, T, arr[MAX][MAX], final_x, final_y;
int dx[] = { -1, 0, 1, 0 };
int dy[] = { 0, 1, 0, -1 };
struct info {
	int x, y, d;
};
bool visited[MAX][MAX];

bool move(int a, int b, int dir) {
	queue <info> q;
	q.push({ a, b, dir });

	while (!q.empty()) {
		int x = q.front().x;
		int y = q.front().y;
		int d = q.front().d;
		q.pop();


		int nx = x + dx[d];
		int ny = y + dy[d];

		if (nx < 1 || nx > n || ny < 1 || ny > n) {
			final_x = nx;
			final_y = ny;
			return true;
		}

		if (!visited[nx][ny] && arr[nx][ny] == 1) {
			d = (d + 1) % 4;
			q.push({ nx, ny, d });
		}
		else if (visited[nx][ny] && arr[nx][ny] == 1) return false;

		else if (arr[nx][ny] == 0) q.push({ nx, ny, d });
	}
}

int main() {
	scanf("%d", &T);

	for (int t = 0; t < T; t++) {
		scanf("%d %d", &n, &r);

		memset(visited, 0, sizeof(visited));
		memset(arr, 0, sizeof(arr));
		for (int i = 0; i < r; i++) {
			int mx, my;
			scanf("%d %d", &mx, &my);

			arr[mx][my] = 1;
		}

		int rx, ry, rd;
		scanf("%d %d", &rx, &ry);

		if (rx == 0) rd = 2;
		else if (rx == n + 1) rd = 0;
		else if (ry == 0) rd = 1;
		else rd = 3;

		if (move(rx, ry, rd)) printf("%d %d\n", final_x, final_y);
		else printf("0 0\n");
	}
	return 0;
}

'코딩테스트 > [BOJ] 문제 풀이' 카테고리의 다른 글

백준 11559 Puyo Puyo  (0) 2021.08.28
백준 5707 Brothers  (0) 2021.08.28
백준 1091 카드 섞기  (0) 2021.08.28
백준 2174 로봇 시뮬레이션  (1) 2021.08.27
백준 10829 이진수 변환  (0) 2021.08.26
Comments