본문 바로가기

코딩테스트/JAVA

[SWEA JAVA] 5650. [모의 SW 역량테스트] 핀볼 게임

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRF8s6ezEDFAUo&categoryId=AWXRF8s6ezEDFAUo&categoryType=CODE&problemTitle=%EB%AA%A8%EC%9D%98&orderBy=SUBMIT_COUNT&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

public class Solution {
	public static int T, N, ans, cnt;
	public static int[][] map;
	public static List<int[]>[] warm;
	public static int[] dr = { -1, 0, 1, 0 };
	public static int[] dc = { 0, 1, 0, -1 };

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		T = Integer.parseInt(br.readLine());
		for (int tc = 1; tc <= T; tc++) {
			// 1. 입력받기
			N = Integer.parseInt(br.readLine().trim());
			map = new int[N][N];
			warm = new ArrayList[11];
			for (int i = 6; i <= 10; i++) {
				warm[i] = new ArrayList<>();
			}
			ans = 0;

			// 1-1. map, warm 입력받기
			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());
					if (map[i][j] > 5) {
						warm[map[i][j]].add(new int[] { i, j });
					}
				}
			}

			// 2. 0인 구역 4방 탐색
			for (int i = 0; i < N; i++) {
				for (int j = 0; j < N; j++) {
					if (map[i][j] == 0) {
						for (int k = 0; k < 4; k++) {
							cnt = 0;
							solve(i, j, k);
							if(cnt > ans) {
								ans = cnt;
							}
						}
					}
				}
			}

			System.out.println("#" + tc + " " + ans);
		}
	}

	public static void solve(int i, int j, int dir) {
		int nr = i + dr[dir];
		int nc = j + dc[dir];
		int k = dir;
		while(true) {
			// 윗벽에 부딪히다.
			if(nr < 0) {
				nr += 1;
				k += 2;
				cnt++;
				continue;
			}
			
			// 아래벽에 부딪히다.
			if(nr >= N) {
				nr -= 1;
				k -= 2;
				cnt++;
				continue;
			}
			
			// 오른쪽벽에 부딪히다.
			if(nc >= N) {
				nc -= 1;
				k += 2;
				cnt++;
				continue;
			}
			
			// 왼쪽벽에 부딪히다.
			if(nc < 0) {
				nc += 1;
				k -= 2;
				cnt++;
				continue;
			}
			
			// 블랙홀
			if(map[nr][nc] == -1) {
				break;
			}
			
			// 자기 자리로 오면
			if(nr == i && nc == j) {
				break;
			}
			
			if(map[nr][nc] > 5) { // 웜홀
				int num = map[nr][nc];
				int[] cur = {nr, nc};
				if(warm[num].get(0)[0] == nr && warm[num].get(0)[1] == nc) {
					nr = warm[num].get(1)[0] + dr[k];
					nc = warm[num].get(1)[1] + dc[k];
				} else {
					nr = warm[num].get(0)[0] + dr[k];
					nc = warm[num].get(0)[1] + dc[k];
				}
			} else if(map[nr][nc] <6 && map[nr][nc] > 0) { // 블록
				switch(map[nr][nc]) {
				case 1:
					if(k == 0) {
						nr +=1;
						k = 2;
					}else if(k == 1) {
						nc -= 1;
						k = 3;
					}
					else if(k == 2) {
						nc += 1;
						k = 1;
					}
					else if(k == 3) {
						nr -= 1;
						k = 0;
					}
						
					break;
				case 2:
					if(k == 0) {
						nc +=1;
						k = 1;
					}else if(k == 1) {
						nc -= 1;
						k = 3;
					}
					else if(k == 2) {
						nr -= 1;
						k = 0;
					}
					else if(k == 3) {
						nr += 1;
						k = 2;
					}
					break;
				case 3:
					if(k == 0) {
						nc -=1;
						k = 3;
					}else if(k == 1) {
						nr += 1;
						k = 2;
					}
					else if(k == 2) {
						nr -= 1;
						k = 0;
					}
					else if(k == 3) {
						nc += 1;
						k = 1;
					}
					break;
				case 4:
					if(k == 0) {
						nr +=1;
						k = 2;
					}else if(k == 1) {
						nr -= 1;
						k = 0;
					}
					else if(k == 2) {
						nc -= 1;
						k = 3;
					}
					else if(k == 3) {
						nc += 1;
						k = 1;
					}
					break;
				case 5:
					if(k == 0) {
						nr +=1;
						k = 2;
					}else if(k == 1) {
						nc -= 1;
						k = 3;
					}
					else if(k == 2) {
						nr -= 1;
						k = 0;
					}
					else if(k == 3) {
						nc += 1;
						k = 1;
					}
					break;
				}
				cnt++;
			} else if(map[nr][nc] == 0) { // 빈공간
				nr = nr + dr[k];
				nc = nc + dc[k];
			}
		}
	}
}

풀이 사항

풀이 일자: 2024.09.12
풀이 시간: 90분
채점 결과: 정답
예상 문제 유형: 구현

풀이 방법

  1. 이중포문으로 맵 전체를 돌며 0인 구역에서 탐색을 진행하고 빠져나온뒤 점수를 계산해 주었다.
  2. 사방 외벽에 부딪히는것들을 먼저 계산해 주었고 점수를 늘리고 방향을 바꿔주었다.
  3. 블록에 부딪힌다면 현재 진행하고 있는 방향에 따라서 스위치문을 통해 방향을 바꿔주었다.
  4. 웜홀이나 블랙홀을 만난다면 미리 저장해 두었던 배열을 참고해서 위치를 이동시키거나 함수를 종료해준다.
  5. 스위치문을 통해 방향을 지정해주는 것보다 이중배열을 만들어서 관리하는것이 훨씬 편하다는것을 알았다.