문제
N 행 N 열로 이루어진 정사각형 격자구조 내에 방들 중에서 몇 개의 방에는 ╱ 또는 ╲ 형태의 대각선으로 45도 기울어진 양면거울이 들어 있다. 거울은 상하좌우에서 오는 빛을 다시 상하좌우 방향의 방으로 직각 반사시킨다. 본 문제에서는 ‘가장 윗줄에서 가장 왼쪽 방’의 왼쪽에서 레이저 포인터로 빛을 수평(0도)으로 비추었을 때 빛이 거치는 서로 다른 거울 개수를 계산하려고 한다.
예를 들어, 위 그림을 보자. 그림에서는 “①” 방으로 들어온 빛이 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이 아닌 값이 들어있는 경우를 모두 더했다.