본문 바로가기
알고리즘/알고리즘 오답노트

SWEA 5650 핀볼게임

by shinyou1024 2020. 5. 30.

시뮬레이션

추억의 핀볼 게임..!

풀이 방식

모든 칸에 4방향으로 핀볼을 놓아본다 빈 칸이 아니면 해당 케이스는 패스

  • 블록 : changeDir 배열을 참조해 다음 방향 지정

    changeDir[i][j] ⇒ j 방향으로 (i+1)블록에 부딪혔을 때 바뀌는 방향

  • 웜홀 : 이차원 리스트로 관리

    1) makeWorm을 통해 (번호-6)의 리스트에 넣어준다

    2) changeWorm을 통해 순간 이동 처리

    ⇒ 첫 번째 웜홀 위치와 같다면 두 번째 웜홀을, 두 번째 웜홀 위치와 같다면 첫 번째 웜홀을 리턴

  • 벽 : 경계 밖을 벗어나면 (d+2)%4를 해준다

    (d+2)%4는 반대방향임

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;

class Solution {
    static class Pos{
        int x, y;

        public Pos(int x, int y) {
            super();
            this.x = x;
            this.y = y;
        }
    }
    static int[][] map;
    static int h, w;
    static int ans;
    static int[][] changeDir = {
            {2, 3, 1, 0},
            {1, 3, 0, 2},
            {3, 2, 0, 1},
            {2, 0, 3, 1},
            {2, 3, 0, 1}
    };
    static List<List<Pos>> worm;
    static void init() {
        map = new int[h][w];
        worm = new ArrayList<List<Pos>>();
        for(int i=0; i<5; i++) {
            worm.add(new ArrayList<Solution.Pos>());
        }

        ans = 0;
    }
    public static void main(String args[]) throws Exception {
        //System.setIn(new FileInputStream("res/input.txt"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = null;
        int T = Integer.parseInt(br.readLine());
        for (int test_case = 1; test_case <= T; test_case++) {
            h = w = Integer.parseInt(br.readLine());
            init();
            for(int i=0; i<h; i++) {
                st = new StringTokenizer(br.readLine());
                for(int j=0; j<w; j++) {
                    map[i][j] = Integer.parseInt(st.nextToken());
                    if(6<=map[i][j]&& map[i][j]<=10) {
                        makeWorm(i, j, map[i][j]);
                    }
                }
            }
            for(int i=0; i<h; i++) {
                for(int j=0; j<w; j++) {
                    if(map[i][j]!=0) continue; 
                    for(int d=0; d<4; d++) {
                        simulation(i, j, d);
                    }
                }
            }

            System.out.println("#"+test_case+" "+ans);
        }
    }
    static int[] dx = {-1, 0, 1, 0}; static int[] dy = {0, 1, 0, -1};
    static void simulation(int sx, int sy, int d) {
        int x = sx; int y = sy;
        int score = 0;
        while(true) {
            x += dx[d]; y += dy[d];
            // 경계 밖 
            if(x<0 || x>h-1 || y<0 || y>w-1) {
                d = (d+2)%4;
                score += 1;
                continue;
            }
            int num = map[x][y];
            // 블랙홀
            if(num==-1) break;
            // 출발위치 
            else if(x==sx && y==sy) break;
            // 웜홀 
            else if(6<=num && num<=10) {
                Pos next = changeWorm(x, y, num);
                x = next.x; y = next.y;
            }
            // 블록 
            else if(1<=num && num<=5) {
                d = changeDir[num-1][d];
                score += 1;
            }
            // 빈칸
        }
        ans = Math.max(ans, score);
    }
    static Pos changeWorm(int x, int y, int num) {
        num -= 6;
        Pos first = worm.get(num).get(0);
        Pos second = worm.get(num).get(1);
        // 첫 번째 => 두 번째 리턴 
        if(x==first.x && y==first.y) return second;
        // 두 번
        else return first;
    }
    static void makeWorm(int x, int y, int num) {
        num -= 6;
        worm.get(num).add(new Pos(x, y));
    }
}

'알고리즘 > 알고리즘 오답노트' 카테고리의 다른 글

백준 16235 나무 재테크  (0) 2020.06.03
백준 1525 퍼즐  (0) 2020.05.30
백준 9376 탈옥  (0) 2020.05.21
백준 1062 가르침  (0) 2020.05.21
SWEA 2112 보호필름  (0) 2020.05.20

댓글