1
+ import java .io .BufferedReader ;
2
+ import java .io .InputStreamReader ;
3
+ import java .util .StringTokenizer ;
4
+
5
+ public class JW_술래잡기_체스 {
6
+
7
+ static int [] dy = { 0 , -1 , -1 , 0 , 1 , 1 , 1 , 0 , -1 };
8
+ static int [] dx = { 0 , 0 , -1 , -1 , -1 , 0 , 1 , 1 , 1 };
9
+ static int max = 0 ;
10
+
11
+ public static void main (String [] args ) throws Exception {
12
+ BufferedReader br = new BufferedReader (new InputStreamReader (System .in ));
13
+ StringTokenizer st ;
14
+ int [][][] board = new int [4 ][4 ][2 ];
15
+ for (int i = 0 ; i < 4 ; i ++) {
16
+ st = new StringTokenizer (br .readLine ());
17
+ for (int j = 0 ; j < 4 ; j ++) {
18
+ int p = Integer .parseInt (st .nextToken ());
19
+ int d = Integer .parseInt (st .nextToken ());
20
+ board [i ][j ] = new int [] { p , d };
21
+ }
22
+ }
23
+ policeMove (0 , 0 , 0 , board );
24
+ System .out .println (max );
25
+ }
26
+
27
+ // 경찰 이동(재귀)
28
+ private static void policeMove (int sum , int y , int x , int [][][] board ) {
29
+ sum += board [y ][x ][0 ]; // 해당 좌표의 값을 합
30
+ max = Math .max (max , sum ); // 최댓값 갱신
31
+ board [y ][x ][0 ] = 0 ; // 해당 좌표의 값을 초기화
32
+ int d = board [y ][x ][1 ]; // 해당 좌표의 방향
33
+ doDookMove (y , x , board ); // 도둑 이동
34
+ // 경찰이 이동할 수 있는 방향을 모두 재귀적으로 탐색
35
+ for (int i = 1 ; i <= 3 ; i ++) {
36
+ int ny = y + dy [d ] * i , nx = x + dx [d ] * i ;
37
+ // 이동할 수 있다면
38
+ if (isValid (ny , nx ) && board [ny ][nx ][0 ] != 0 ) {
39
+ int [][][] nextBoard = copyBoard (board );
40
+ policeMove (sum , ny , nx , nextBoard ); // 재귀 호출
41
+ }
42
+ }
43
+ }
44
+
45
+ // 도둑 이동
46
+ private static void doDookMove (int py , int px , int [][][] board ) {
47
+ // 순서에 따라서 이동
48
+ next : for (int p = 1 ; p <= 16 ; p ++) {
49
+ for (int y = 0 ; y < 4 ; y ++)
50
+ for (int x = 0 ; x < 4 ; x ++)
51
+ // 순서에 맞는 좌표를 찾았다면
52
+ if (board [y ][x ][0 ] == p ) {
53
+ int d = board [y ][x ][1 ];
54
+ int ny = y + dy [d ], nx = x + dx [d ];
55
+ // 이동할 수 있는 좌표가 등장할 때까지 회전
56
+ while (!isValid (ny , nx ) || (ny == py && nx == px )) {
57
+ d ++;
58
+ d %= 9 ;
59
+ if (d == 0 )
60
+ d = 1 ;
61
+ ny = y + dy [d ];
62
+ nx = x + dx [d ];
63
+ }
64
+ swap (y , x , ny , nx , board ); // 스왑
65
+ board [ny ][nx ][1 ] = d ; // 새로운 방향으로 변경
66
+ continue next ; // 발견했다면 다음 순서 진행
67
+ }
68
+ }
69
+ }
70
+
71
+ // 두 좌표에 있는 원소를 스왑해주는 함수
72
+ private static void swap (int y , int x , int ny , int nx , int [][][] board ) {
73
+ int [] temp = board [y ][x ];
74
+ board [y ][x ] = board [ny ][nx ];
75
+ board [ny ][nx ] = temp ;
76
+ }
77
+
78
+ // 기존의 배열을 복사하여 다음 배열을 만들어주는 함수
79
+ private static int [][][] copyBoard (int [][][] board ) {
80
+ int [][][] nextBord = new int [4 ][4 ][2 ];
81
+ for (int i = 0 ; i < 4 ; i ++)
82
+ for (int j = 0 ; j < 4 ; j ++)
83
+ nextBord [i ][j ] = board [i ][j ].clone ();
84
+ return nextBord ;
85
+ }
86
+
87
+ // 경계 체크 함수
88
+ private static boolean isValid (int y , int x ) {
89
+ return 0 <= y && y < 4 && 0 <= x && x < 4 ;
90
+ }
91
+ }
0 commit comments