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;
    }
}