https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRF8s6ezEDFAUo
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
www.swexpertacademy.com
이 문제에서 어려웠던 부분은 웜홀 부분인 것 같다.
나는 웜홀의 좌표를 저장할 Wormhole클래스를 만들고 배열에 넣어주었다.
2차원 배열에 넣어서 각 6~10 번호마다 두 개씩 이므로 배열의 크기는 5X2가 된다. (웜홀은 쌍으로 존재하므로)
웜홀이 더 적게 존재할수도 있지만 최대 5개밖에 안되므로 그냥 한 번에 배열로 만들어줬다.
웜홀 배열의 각 좌표의 초기값을 -1로 설정해주고 이 점을 이용해서 두 개의 쌍을 차례대로 넣어준다.
예전에는 클래스를 만드는 대신에 3차원 int배열로 만들어 줬었다.(5X2X2 크기)
핀볼의 이동
- 출발 위치와 진행 방향을 임의로 설정하여 점수의 최댓값을 구하는 문제이므로 모든 빈 칸(값이 0인 칸)에서 각 네 방향으로 출발해서 모든 경우의 점수를 구한다.
- 각 이동에서는 블록의 모양에 따라서 적절히 방향을 잘 바꾸어 주며 이동시키고 블록이나 벽에 부딪힐 경우(범위 벗어나는 경우) 점수를 증가시킨다.
- 웜홀을 만난 경우에는 방향을 유지한 채 반대편 웜홀로 이동한다.
- 조건에 따라 핀볼이 출발 위치로 돌아오거나 블랙홀에 빠지는 경우가 될때까지 while문을 이용해 핀볼의 이동을 반복한다.
- 핀볼의 이동이 끝나면 그때의 점수를 현재 최대 점수와 비교해준다.
import java.io.*;
import java.util.*;
public class Solution {
static class Wormhole {
int x;
int y;
Wormhole(int x, int y) {
this.x = x;
this.y = y;
}
}
static int N, max;
static int[][] map;
static int[] dx = {1,-1,0,0};
static int[] dy = {0,0,1,-1};
static Wormhole[][] holeArr;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
for(int tc=1; tc<=T; tc++) {
N = Integer.parseInt(br.readLine());
StringTokenizer st;
map = new int[N][N];
holeArr = new Wormhole[5][2];
//웜홀의 위치 초기화
for(int i=0; i<5; i++) {
for(int j=0; j<2; j++) {
holeArr[i][j] = new Wormhole(-1,-1);
}
}
for(int i=0; i<N; i++) {
st = new StringTokenizer(br.readLine());
for(int j=0; j<N; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
//웜홀인 경우
//6번 웜홀부터 시작하므로 6번 웜홀이 0번째 index가 된다. 7번이 1, 8번이 2,,,
if(map[i][j] >= 6) {
//웜홀 첫 번째
if(holeArr[map[i][j]-6][0].x == -1 && holeArr[map[i][j]-6][0].y == -1) {
holeArr[map[i][j]-6][0].x = i;
holeArr[map[i][j]-6][0].y = j;
} else { //이미 첫 번째 웜홀의 위치가 저장되어 있는 경우 반대편 웜홀 저장
holeArr[map[i][j]-6][1].x = i;
holeArr[map[i][j]-6][1].y = j;
}
}
}
}
max = 0;
for(int i=0; i<N; i++) {
for(int j=0; j<N; j++) {
//빈칸이 아닌경우(블록이나 웜홀, 블랙홀인 경우)
if(map[i][j] != 0) continue;
//상하좌우 각 방향으로 출발
for(int k=0; k<4; k++) {
move(i,j,k);
}
}
}
System.out.println("#"+tc+" "+max);
}
}
static void move(int x, int y, int dir) {
int nx = x;
int ny = y;
int point = 0;
while(true) {
//이동
nx += dx[dir];
ny += dy[dir];
//벽에 부딪힌 경우 점수 증가하고 방향 전환
if(nx < 0 || ny < 0 || nx >= N || ny >= N) {
point++;
if(dir == 0 || dir == 2) {
dir++;
} else {
dir--;
}
continue;
}
//블랙홀에 빠짐
if(map[nx][ny] == -1) {
break;
}
//출발위치로 돌아옴
if(x == nx && y == ny) {
break;
}
if(map[nx][ny] == 0) {
//빈칸이므로 방향유지한채 바로 이동
continue;
} else if(map[nx][ny] == 1) { //각 블록의 종류에따라서 방향을 변환해주고 점수도 증가
if(dir == 0) {
dir = 2;
} else if(dir == 1) {
dir = 0;
} else if(dir == 2) {
dir = 3;
} else {
dir = 1;
}
point++;
} else if(map[nx][ny] == 2) {
if(dir == 0) {
dir = 1;
} else if(dir == 1) {
dir = 2;
} else if(dir == 2) {
dir = 3;
} else {
dir = 0;
}
point++;
} else if(map[nx][ny] == 3) {
if(dir == 0) {
dir = 1;
} else if(dir == 1) {
dir = 3;
} else if(dir == 2) {
dir = 0;
} else {
dir = 2;
}
point++;
} else if(map[nx][ny] == 4) {
if(dir == 0) {
dir = 3;
} else if(dir == 1) {
dir = 0;
} else if(dir == 2) {
dir = 1;
} else {
dir = 2;
}
point++;
} else if(map[nx][ny] == 5) {
if(dir == 0 || dir == 2) {
dir++;
} else {
dir--;
}
point++;
} else { //웜홀인 경우 반대편 웜홀로 이동
int holenum = map[nx][ny]-6;
if(nx == holeArr[holenum][0].x && ny == holeArr[holenum][0].y) {
nx = holeArr[holenum][1].x;
ny = holeArr[holenum][1].y;
} else {
nx = holeArr[holenum][0].x;
ny = holeArr[holenum][0].y;
}
}
}
//이동이 끝난 후에 점수 비교
if(max < point) {
max = point;
}
}
}
'SWEA > 모의 SW 역량테스트(JAVA)' 카테고리의 다른 글
| [SWEA] 4014. [모의 SW 역량테스트] 활주로 건설 (0) | 2019.05.26 |
|---|---|
| [SWEA] 2112. [모의 SW 역량테스트] 보호 필름 (0) | 2019.05.24 |
| [SWEA] 2105. [모의 SW 역량테스트] 디저트 카페 (0) | 2019.05.20 |
| [SWEA] 4013. [모의 SW 역량테스트] 특이한 자석 (0) | 2019.05.15 |
| [SWEA] 5644. 무선 충전 (0) | 2019.05.10 |
