SueBeen Park

SueBeen Park

Developer. NewBie

© 2021

Dark Mode

SCPC 1회 예선: 방속의 거울

문제

N 행 N 열로 이루어진 정사각형 격자구조 내에 방들 중에서 몇 개의 방에는 ╱ 또는 ╲ 형태의 대각선으로 45도 기울어진 양면거울이 들어 있다. 거울은 상하좌우에서 오는 빛을 다시 상하좌우 방향의 방으로 직각 반사시킨다. 본 문제에서는 ‘가장 윗줄에서 가장 왼쪽 방’의 왼쪽에서 레이저 포인터로 빛을 수평(0도)으로 비추었을 때 빛이 거치는 서로 다른 거울 개수를 계산하려고 한다.

image1

예를 들어, 위 그림을 보자. 그림에서는 “①” 방으로 들어온 빛이 6번의 반사를 거친 후 3 ⅹ 3 크기의 격자구조 밖으로 빠져나간다. 그 중 “②” 방에 있는 거울의 경우, 한 거울의 양쪽 면에서 두 번의 반사가 일어난 것이다. 따라서 위의 예에서 빛을 반사한 거울은 5개이다. 이 문제를 해결하는 프로그램을 작성하시오.

입력

입력 파일에는 여러 개의 테스트 케이스가 포함되어 있다. 파일의 첫째 줄에는 테스트 케이스 개수를 나타내는 자연수 T 가 주어지고, 이후 차례로 T 개의 테스트 케이스가 주어진다. ( 1≤T≤20) 각각의 테스트 케이스 첫 번째 줄에는 정사각형 격자구조의 ‘한 변의 방 개수’를 나타내는 정수 N 이 주어진다. ( 1≤N≤1,000 ) 다음 줄부터는 N 개의 줄이 주어지고, 각 줄마다 N 개의 문자가 주어진다, 각 문자는 { ‘0’, ‘1’ , ‘2’ }에 속하는 문자 중 하나이다. 문자 ‘1’은 우측 상단에서 좌측 하단으로 45도 기울어진 양면거울이 그 방에 있다는 것을 나타내며, 문자 ‘2’는 좌측 상단에서 우측 하단으로 45도 기울어진 양면거울이 그 방에 있다는 것을 나타낸다. 그리고 문자 ‘0’은 거울이 없는 방임을 나타낸다. 각 줄에 들어 있는 문자들 사이에 빈칸(공백)은 없다.

출력

각 테스트 케이스의 답을 순서대로 표준출력으로 출력하여야 하며, 각 테스트 케이스마다 첫 줄에 “Case #T”를 출력하여야 한다. 이때 T는 테스트 케이스의 번호이다. 그 다음 줄에는 정사각형 격자구조 건물의 ‘맨 위 맨 왼쪽 방’의 왼쪽에서 수평(0도)으로 들어간 빛이 그 건물을 빠져나올 때까지 거치는 서로 다른 거울의 개수를 출력한다.

import java.util.Scanner;

class Solution {
	static int Answer;
	static int[][] direction = { {0,1},{0,-1},{1,0},{-1,0} };	//동 서 남 북
	
	static void solve(int N, int[][] arr) {
		int[][] check = new int[N][N];
		int now = 0;	// 처음 방향은 동쪽
		int x=0,y=0;
		
		while(true) {
			if(arr[x][y]==1){
				now = 3-now;
				check[x][y]++;
			} else if(arr[x][y]==2) {
				now = (now+2) % 4;
				check[x][y]++;
			}
			x+=direction[now][0];
			y+=direction[now][1];
			
			if(x<0 || y<0 || x>=N || y>=N) break;
		}
		
		for(int i=0; i<N; i++) {
			for(int j=0; j<N; j++) {
				if(check[i][j] != 0) Answer++;
			}
		}
		
	}
	
	public static void main(String args[]) throws Exception	{
		
		Scanner sc = new Scanner(System.in);

		int T = sc.nextInt();
		for(int test_case = 0; test_case < T; test_case++) {

			Answer = 0;
			
			int N = sc.nextInt();
			boolean[][] check = new boolean[N][N];
			int[][] r = new int[N][N];
			
			sc.nextLine();
			for(int i=0; i<N; i++) {
				String line = sc.nextLine();
				for(int j=0; j<N; j++) {
					r[i][j] = line.charAt(j) - '0';
				}
			}
			
			solve(N, r);
			
			System.out.println("Case #"+(test_case+1));
			System.out.println(Answer);
		}
	}
}

코드 설명

방의 정보를 띄어쓰기 없이 받아야 하므로 string으로 받아서 int 자료형으로 바꿔서 저장했다.

그리고 solve함수에서는 방향에 따라 x,y값 변경을 위해 2차배열로 저장해두었다. (동 서 남 북 순으로)

처음 시작점은 0, 0 에서 각 방향에 따라 x, y값을 변경해주고 거울이 있는 방이였을 경우에 check배열의 값을 ++해줘서 나중에 check배열에 0이 아닌 값이 들어있는 경우를 모두 더했다.

문제출처 : codeground