1+ import Foundation
2+
3+ let nq = readLine ( ) !. split { $0 == " " } . map { Int ( String ( $0) ) ! }
4+ var n = Int ( pow ( 2.0 , Double ( nq [ 0 ] ) ) )
5+ let q = nq [ 1 ]
6+
7+ var map = [ [ Int] ] ( )
8+ for _ in 0 ..< n {
9+ let line = readLine ( ) !. split { $0 == " " } . map { Int ( String ( $0) ) ! }
10+ map. append ( line)
11+ }
12+
13+ let ls = readLine ( ) !. split { $0 == " " } . map { Int ( String ( $0) ) ! }
14+
15+ for l in ls {
16+ // 1. 2^L x 2^L 크기의 부분 격자들을 시계 방향으로 90도 회전
17+ if l > 0 {
18+ let rotateSize = Int ( pow ( 2.0 , Double ( l) ) )
19+ map = rotateMatrix ( matrix: map, rotateSize: rotateSize)
20+ }
21+
22+ // 2. 얼음이 녹는 과정 (동시성 고려)
23+ map = meltIce ( matrix: map)
24+ }
25+
26+ // 3. 최종 결과 계산
27+ let totalIce = sumAllElements ( in: map)
28+ let largestMass = findLargestMass ( in: map)
29+
30+ print ( totalIce)
31+ print ( largestMass)
32+
33+
34+ func rotateMatrix( matrix: [ [ Int ] ] , rotateSize: Int ) -> [ [ Int ] ] {
35+ let size = matrix. count
36+ var newMatrix = matrix // 회전 결과를 담을 새로운 배열
37+
38+ // 쿼드 트리 분할 및 회전
39+ for r in stride ( from: 0 , to: size, by: rotateSize) {
40+ for c in stride ( from: 0 , to: size, by: rotateSize) {
41+ rotateSubMatrixInPlace ( & newMatrix, startX: c, startY: r, size: rotateSize)
42+ }
43+ }
44+ return newMatrix
45+ }
46+
47+ func rotateSubMatrixInPlace< T> ( _ matrix: inout [ [ T ] ] , startX: Int , startY: Int , size: Int ) {
48+ // 1. 전치 (Transpose)
49+ for row in 0 ..< size {
50+ for col in row..< size {
51+ let temp = matrix [ startY + row] [ startX + col]
52+ matrix [ startY + row] [ startX + col] = matrix [ startY + col] [ startX + row]
53+ matrix [ startY + col] [ startX + row] = temp
54+ }
55+ }
56+ // 2. 각 행을 뒤집기 (Column Reversal)
57+ for row in 0 ..< size {
58+ for col in 0 ..< size / 2 {
59+ let temp = matrix [ startY + row] [ startX + col]
60+ matrix [ startY + row] [ startX + col] = matrix [ startY + row] [ startX + size - 1 - col]
61+ matrix [ startY + row] [ startX + size - 1 - col] = temp
62+ }
63+ }
64+ }
65+
66+ func meltIce( matrix: [ [ Int ] ] ) -> [ [ Int ] ] {
67+ let rows = matrix. count
68+ let cols = matrix [ 0 ] . count
69+ var newMatrix = matrix // 녹은 결과를 담을 새로운 배열
70+
71+ let directions = [ ( - 1 , 0 ) , ( 1 , 0 ) , ( 0 , - 1 ) , ( 0 , 1 ) ]
72+
73+ for r in 0 ..< rows {
74+ for c in 0 ..< cols {
75+ // 얼음이 있는 칸만 확인
76+ guard matrix [ r] [ c] > 0 else { continue }
77+ var adjacentCount = 0
78+
79+ for (dr, dc) in directions {
80+ let neighborR = r + dr
81+ let neighborC = c + dc
82+
83+ // 인접 칸이 유효 범위 내에 있고, 얼음이 있다면 카운트
84+ if neighborR >= 0 && neighborR < rows && neighborC >= 0 && neighborC < cols && matrix [ neighborR] [ neighborC] > 0 {
85+ adjacentCount += 1
86+ }
87+ }
88+
89+ // 인접한 얼음 칸이 3개 미만이면 녹임
90+ if adjacentCount < 3 {
91+ newMatrix [ r] [ c] -= 1
92+ }
93+ }
94+ }
95+ return newMatrix
96+ }
97+
98+ func sumAllElements( in matrix: [ [ Int ] ] ) -> Int {
99+ return matrix. reduce ( 0 ) { total, row in
100+ total + row. reduce ( 0 , + )
101+ }
102+ }
103+
104+ func findLargestMass( in matrix: [ [ Int ] ] ) -> Int {
105+ guard !matrix. isEmpty else { return 0 }
106+ let rows = matrix. count
107+ let cols = matrix [ 0 ] . count
108+ var visited = Array ( repeating: Array ( repeating: false , count: cols) , count: rows)
109+ var maxMass = 0
110+ let directions = [ ( 0 , 1 ) , ( 0 , - 1 ) , ( 1 , 0 ) , ( - 1 , 0 ) ]
111+
112+ for r in 0 ..< rows {
113+ for c in 0 ..< cols {
114+ if matrix [ r] [ c] > 0 && !visited[ r] [ c] {
115+ var currentMass = 0
116+ var queue = [ ( row: Int, col: Int) ] ( )
117+
118+ queue. append ( ( r, c) )
119+ visited [ r] [ c] = true
120+
121+ var queueIndex = 0
122+ while queueIndex < queue. count {
123+ let current = queue [ queueIndex]
124+ queueIndex += 1
125+
126+ let currentRow = current. row
127+ let currentCol = current. col
128+ currentMass += 1 // 덩어리 크기를 1씩 증가
129+
130+ for (dr, dc) in directions {
131+ let nextRow = currentRow + dr
132+ let nextCol = currentCol + dc
133+
134+ if nextRow >= 0 && nextRow < rows && nextCol >= 0 && nextCol < cols &&
135+ !visited[ nextRow] [ nextCol] && matrix [ nextRow] [ nextCol] > 0 {
136+
137+ visited [ nextRow] [ nextCol] = true
138+ queue. append ( ( row: nextRow, col: nextCol) )
139+ }
140+ }
141+ }
142+ maxMass = max ( maxMass, currentMass)
143+ }
144+ }
145+ }
146+ return maxMass
147+ }
0 commit comments