[SWEA]핀볼 게임

onyoo·2023년 11월 12일
0

알고리즘

목록 보기
29/40

개요

시키는데로 하면 되는 문제
코드 중복이 조금 있어서 이후에 리팩토링하는게 필요할것같다..ㅎㅎ;

문제분석

조건을 그대로 구현하면 되는문제다.
아래의 그림처럼, 1,2,3,4 블록에 부딪힐때 어느 방향으로 튕겨 나가는지 조건을 선언해준다.


웜홀의 경우 ArrayList[] 를 선언해준다음,웜홀을 저장해준다.
웜홀은 무조건 한쌍으로 이루어져있기 때문에 왔다갔다 할 수 있다.

문제풀이

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
 
/**
 * @author onyoo
 * @performance
 * @category
 * @note
 * @see
 * https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWXRF8s6ezEDFAUo
 * @since 2023/11/08
 **/
public class Solution {
    static class Point{
        int x,y;
 
        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
    static int T,N,max;
    static int[][] map;
    static Point[] dir = {
        new Point(0,1),
        new Point(0,-1),
        new Point(1,0),
        new Point(-1,0)
    };
    //오른쪽 왼쪽 아래 위
    static ArrayList<Point>[] warmHole;
    static Point start;
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
 
        T = Integer.parseInt(br.readLine());
 
        for(int t=1;t<T+1;t++){
 
            N = Integer.parseInt(br.readLine().trim());
            map = new int[N][N];
            warmHole = new ArrayList[11];
            for(int i=0;i<=10;i++) warmHole[i] = new ArrayList<>();
            // 최대 다섯쌍
            // 시작위치가 6이기 때문에 이것 고려해서 저장
            max = Integer.MIN_VALUE;
 
            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) {
                        warmHole[map[i][j]].add(new Point(i,j));
                    }
                }
            }
            for(int i=0;i<N;i++){
                for(int j=0;j<N;j++){
                    if(map[i][j] == 0) {
                        start = new Point(i,j);
                        for (int d = 0; d < 4; d++) {
                            go(i, j, d,0);
                        }
                    }
                }
            }
 
            System.out.printf("#%d %d\n",t,max);
 
        }
    }
    static void go(int x,int y,int d,int count){
        // x,y 시작점
        // d 방향
        int nx = x + dir[d].x ;
        int ny = y + dir[d].y;
 
        while(true){;
            if(nx < 0 || ny < 0 || nx >= N || ny >= N) {
                d = reverse(d);
                nx += dir[d].x;
                ny += dir[d].y;
                count++;
                continue;
            }//벽에 부딪히는 경우
 
            int next = map[nx][ny];
 
            if(next == -1 || (nx == start.x && ny == start.y)) {
                max = Math.max(max,count);
                break;
            }
            // 블랙홀에 들어가거나
            // 원래 위치로 돌아오게 되면 종료한다
 
            if(next > 0 && next <= 5){
                switch (next){
                    case 1:
                        if(d == 2|| d == 1){
                            if(d == 2) d = 0;
                            else d = 3;
                        }
                        else d = reverse(d);
                        break;
                    case 2:
                        if(d == 3 || d == 1){
                            if(d == 3) d = 0;
                            else d = 2;
                        }
                        else d =reverse(d);
                        break;
                    case 3:
                        if(d == 3 || d == 0){
                            if(d == 3) d = 1;
                            else d = 2;
                        }
                        else d = reverse(d);
                        break;
                    case 4:
                        if(d == 2 || d == 0){
                            if(d == 2) d = 1;
                            else d = 3;
                        }
                        else d = reverse(d);
                        break;
                    case 5:
                        d = reverse(d);
                        break;
                }
                count++;
            }
            //블록에 부딪히는 경우
 
            if(next > 5){
                ArrayList<Point> p = warmHole[next];
                Point arrive= null;
 
                for(Point point : p){
                    if(point.x == nx && point.y == ny) continue;
                    arrive = point; // 이동 위치 저장
                }
 
                nx = arrive.x;
                ny = arrive.y;
            }
            //웜홀에 부딪히는 경우
            nx += dir[d].x;
            ny += dir[d].y;
 
        }
    }
    static int reverse(int d){
        if(d % 2 == 0) d++;
        else d--;
        return d;
    }
}
profile
반갑습니다 ! 백엔드 개발 공부를 하고있습니다.

0개의 댓글