티스토리 뷰

생각

핀볼 게임을 진행한다. 이 핀볼게임에는 블랙홀과 웜홀, 다양한 모양의 블록이 있다. 1) 블랙홀 블랙홀은 -1로 주어지며 블랙홀에 들어가면 게임이 끝난게 된다. 2) 웜홀 웜홀은 항상 쌍으로 주어지며 6~10번으로 주어진다. 웜홀로 들어가면 쌍을 이룬 다른 웜홀로 나와 진행하던 방향대로 진행한다. 3) 블록 블록은 1~5로 주어지며 아래와 같은 모양을 가지고 있다. 게임을 진행할 때, 맵 둘레의 벽에 부딪히거나 블록에 부딪히면 +1 점을 얻을 수 있을 때, 가장 높은 점수를 구하시오. (단, 핀볼의 시작 위치와 방향은 맘대로 결정할 수 있으며, 게임은 블랙홀에 빠지거나 처음 시작위치에 다시 되돌아오면 끝나게 된다.)


처음 생각

우선 시뮬레이션으로 구현을 해주어야하고, 블록의 모양과 웜홀을 관리해줘야 한다 생각하였다.

▶ 블록은 swich case문으로 모양별로 일일이 구분해주었고, 웜홀은 Wall class를 만들어 x,y,x2,y2로 쌍을 관리해주었다.


다음 생각

맵을 상하좌우 1칸 씩 늘려 둘레를 5번 블록으로 매꿔도 되지만(벽에 부딪힐 경우 +1점 후 반대방향이므로) 그대로 두어서 맵 밖으로 나갈경우를 탐색하여 +1점 후 처리를 해주었다. 이렇게 맵 밖으로 나가는 경우를 따로 처리해 줄경우 아래 그림과 같이 바로 블록을 만날 경우와 웜홀을 만날 경우를 생각해 주어야한다. 앞으로 한 칸씩 나가면서 진행하고 있기 때문에 범위 밖으로나간 if문에서 바로 처리를 안해줄 경우 다음번 탐색시 무시하고 지나가기 때문이다.



다다음 생각

위에까지 해준 후 제출했더니 0/50 런타임 에러가 나왔다. 댓글을 보니 BufferedReader를 사용시 오류가 난다는 말이 있었고, Scanner로 고쳐 통과하였다.

▶ Input 파일이 잘 못 된것 같다.


방안

1) 모든 경우를 탐색하였는데 실상 경계 벽에 부딪히거나 5번 블록 같이 다시 되돌아오는 상황이면 이전에 왔던 경로들로 다시 되돌아가므로 되돌아가지 않고 점수만 *2(이전 되돌아온길) +1(방금 부딪힌 블록) 해주어도 된다. 


2) 블록이 최대 5개로 주어져서 하드코딩으로 모든 케이스를 적어주었는데, 짧막하게 배열로 만들어서 인덱스 값에 맞춰서 바꿔줘도 될 것 같다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;
 
class Solution {
    static int n;
    static int[][] arr;
    static List<Holl> list = new ArrayList<>();
    public static void main(String[] args) throws IOException{
        Scanner sc = new Scanner(System.in);
        int tc = sc.nextInt();
        StringBuilder sb = new StringBuilder();
        for(int i=1;i<=tc;i++) {
            n = sc.nextInt();
            arr = new int[n][n];
            // 웜홀 초기화 6~10
            list.clear();
            for(int j=0;j<5;j++)
                list.add(new Holl(-1-1-1-1));
            
            // 입력 받기
            for(int j=0;j<n;j++) {
                for(int k=0;k<n;k++) {
                    arr[j][k] = sc.nextInt();
                    if(arr[j][k]>=6) {
                        if(list.get(arr[j][k]-6).x==-1) {
                            list.get(arr[j][k]-6).x = j;
                            list.get(arr[j][k]-6).y = k;
                        }else {
                            list.get(arr[j][k]-6).x2 = j;
                            list.get(arr[j][k]-6).y2 = k;
                        }
                    }
                }
            }
            
            result = 0;
            for(int j=0;j<n;j++) {
                for(int k=0;k<n;k++) {
                    if(arr[j][k]==0)
                        solve(j,k);
                }
            }
            sb.append("#"+i+" "+result+"\n");
        }
        System.out.print(sb);
    }
    
    static int result;
    private static void solve(int x,int y) {
        Queue<Pair> queue = new LinkedList<>();
        // 네 방향 넣어주기,
        for(int i=1;i<=4;i++)
            queue.add(new Pair(x,y,i,0));
        // 맨 처음 공 출발지점 도착아니기 위해서.
        int cnt=0;
        while(!queue.isEmpty()) {
            Pair t = queue.poll();
            // 출발 위치로 돌아온 경우 끝
            cnt++;
            int tx=t.x, ty=t.y;
            if(tx==&& ty==&& cnt>4) {
                result = Math.max(result, t.score);
                continue;
            }
            switch (t.d) {
            case 1: tx-=1break// 상
            case 2:    tx+=1break// 하
            case 3:    ty-=1break// 좌
            case 4:    ty+=1break// 우
            }
            // 맵 밖으로 나감 -> 벽에서 나간 것.(부딪히게 하자)
            if(tx<0 || ty<0 || tx>=|| ty>=n) {
                // 방향 반대로 바꿔주기
                switch (t.d) {
                case 1: t.d=2break;
                case 2:    t.d=1break;
                case 3:    t.d=4break;
                case 4:    t.d=3break;
                }
                // 부딪힌 거니 점수 & 벗어나긴 전 위치 값으로 방향,점수만 변경
                t.score++;
                if(arr[t.x][t.y]!=0) {
                    if(arr[t.x][t.y]>=6) {
                        // 웜홀
                        int wx = list.get(arr[t.x][t.y]-6).x;
                        int wy = list.get(arr[t.x][t.y]-6).y;
                        int wx2 = list.get(arr[t.x][t.y]-6).x2;
                        int wy2 = list.get(arr[t.x][t.y]-6).y2;
                        if(t.x==wx&&t.y==wy) {
                            queue.add(new Pair(wx2, wy2, t.d, t.score));
                        }else {
                            queue.add(new Pair(wx, wy, t.d, t.score));
                        }
                    }else {
                        // 벽돌 -> 방향 이동해주기
                        t.d = wall(t.x, t.y, t.d);
                        queue.add(new Pair(t.x, t.y, t.d, t.score+1));
                    }
                }else {
                    queue.add(new Pair(t.x, t.y, t.d, t.score));
                }
                continue;
            }
            
            // 벽돌, 블랙홀, 웜홀 확인
            if(arr[tx][ty]==0) {
                // 1) 일반길 -> 갈 수 있는곳 까지 보내주자.
                queue.add(new Pair(tx, ty, t.d, t.score));
            }else if(arr[tx][ty]==-1) {
                // 2) 블랙홀 -> 점수계산
                result = Math.max(result, t.score);
            }else if(arr[tx][ty]<6) {
                // 3) 벽돌 -> 방향 이동해주기
                t.d = wall(tx, ty, t.d);
                queue.add(new Pair(tx, ty, t.d, t.score+1));
            }else {
                // 4) 웜홀 이동(2개 쌍) -> 방향 그대로 점수 X
                int wx = list.get(arr[tx][ty]-6).x;
                int wy = list.get(arr[tx][ty]-6).y;
                int wx2 = list.get(arr[tx][ty]-6).x2;
                int wy2 = list.get(arr[tx][ty]-6).y2;
                if(tx==wx&&ty==wy) {
                    queue.add(new Pair(wx2, wy2, t.d, t.score));
                }else {
                    queue.add(new Pair(wx, wy, t.d, t.score));
                }
            }
        }
    }
    
    private static int wall(int x,int y,int d) {
        switch (arr[x][y]) {
        case 1:
            if(d==1)       return 2// 상->하
            else if(d==2return 4// 하->우
            else if(d==3return 1// 좌->상
            else if(d==4return 3// 우->좌
            break;
        case 2:
            if(d==1)       return 4// 상->우
            else if(d==2return 1// 하->상
            else if(d==3return 2// 좌->하
            else if(d==4return 3// 우->좌
            break;
        case 3:
            if(d==1)       return 3// 상->좌
            else if(d==2return 1// 하->상
            else if(d==3return 4// 좌->우
            else if(d==4return 2// 우->하
            break;
        case 4:
            if(d==1)       return 2// 상->하
            else if(d==2return 3// 하->좌
            else if(d==3return 4// 좌->우
            else if(d==4return 1// 우->상
            break;
        case 5:
            if(d==1)       return 2// 상->하
            else if(d==2return 1// 하->상
            else if(d==3return 4// 좌->우
            else if(d==4return 3// 우->좌
            break;
        }
        return 0;
    }
    
    static class Pair{
        private int x,y,d,score;
        public Pair(int x,int y,int d,int score) {
            this.x = x;
            this.y = y;
            this.d = d;
            this.score = score;
        }
    }
    
    static class Holl{
        private int x,y,x2,y2;
        public Holl(int x,int y,int x2,int y2) {
            this.x = x;
            this.y = y;
            this.x2 = x2;
            this.y2 = y2;
        }
    }
}
cs

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday