solution.java
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
import java.io.*;
import java.util.*;
public class Solution {
static int N, M;
static int[][] board;
static int BLACK = 1;
static int WHITE = 2;
// 북, 북동, 동, 남동, 남, 남서, 서, 북서
static int[] dr = {-1, -1, 0, 1, 1, 1, 0, -1};
static int[] dc = {0, 1, 1, 1, 0, -1, -1, -1};
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int T = Integer.parseInt(br.readLine());
for (int t = 1; t <= T; t++) {
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
board = new int[N + 1][N + 1];
// 보드 초기 세팅
int rs = N / 2;
int re = N / 2 + 1;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if ((i == rs && j == rs) || (i == re && j == re)) {
board[i][j] = WHITE;
} else if ((i == rs && j == re) || (i == re && j == rs)) {
board[i][j] = BLACK;
}
}
}
// M번 돌 놓기
for (int i = 0; i < M; i++) {
st = new StringTokenizer(br.readLine());
int c = Integer.parseInt(st.nextToken());
int r = Integer.parseInt(st.nextToken());
int rock = Integer.parseInt(st.nextToken());
simulate(r, c, rock);
}
// 돌 개수 세기
int wCnt = 0;
int bCnt = 0;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (board[i][j] == WHITE) wCnt++;
else if (board[i][j] == BLACK) bCnt++;
}
}
sb.append('#').append(t).append(' ').append(bCnt).append(' ').append(wCnt).append('\n');
}
System.out.println(sb.toString());
}
static void simulate(int r, int c, int rock) {
board[r][c] = rock;
for (int d = 0; d < 8; d++) {
boolean can = checkCanReverse(r, c, d, rock);
if (checkCanReverse(r, c, d, rock)) {
// 뒤집기 작업
int tr = r + dr[d];
int tc = c + dc[d];
int targetRock = (rock == WHITE) ? BLACK : WHITE;
while (tr > 0 && tr <= N && tc > 0 && tc <= N && board[tr][tc] == targetRock) {
board[tr][tc] = rock;
tr += dr[d];
tc += dc[d];
}
}
}
}
static boolean checkCanReverse(int r, int c, int d, int rock) {
int tr = r + dr[d];
int tc = c + dc[d];
int targetRock = (rock == WHITE) ? BLACK : WHITE;
// d 방향으로 1칸씩 가면서 rock 색상을 다시 만나면 뒤집기 가능함.
// rock 색을 만나기 전에 targetRock 색이 중간에 끊겨도 뒤집기 불가능
while (tr > 0 && tr <= N && tc > 0 && tc <= N && board[tr][tc] == targetRock) {
tr += dr[d];
tc += dc[d];
}
if (tr <= 0 || tr > N || tc <= 0 || tc > N) {
return false;
}
if (board[tr][tc] == rock) {
return true;
}
return false;
}
}