1+ let inputs = readLine ( ) !. split ( separator: " " ) . compactMap { Int ( $0) }
2+ let n = inputs [ 0 ] // 행의 개수
3+ let m = inputs [ 1 ] // 열의 개수
4+ let g = inputs [ 2 ] // 초록색 배양액 개수
5+ let r = inputs [ 3 ] // 빨간색 배양액 개수
6+ var board = Array ( repeating: Array ( repeating: " " , count: m) , count: n)
7+ var sprinkable : [ ( Int , Int ) ] = [ ]
8+ var queue : [ ( Int , Int ) ] = [ ]
9+ var vist : [ [ ( String , Int ) ] ] = [ ]
10+
11+ for i in 0 ..< n {
12+ let input = readLine ( ) !. split ( separator: " " ) . map { String ( $0) }
13+ for j in 0 ..< m {
14+ if input [ j] == " 2 " { sprinkable. append ( ( i, j) ) }
15+ board [ i] [ j] = input [ j]
16+ }
17+ }
18+
19+ var rCombi = Array ( repeating: ( - 1 , - 1 ) , count: r)
20+ var gCombi = Array ( repeating: ( - 1 , - 1 ) , count: g)
21+ var isUsed = Array ( repeating: false , count: sprinkable. count)
22+ var result = 0
23+
24+ recursiveR ( 0 , index: 0 )
25+ print ( result)
26+
27+ // 1. 배양액 뿌릴 수 있는 좌표 탐색 - 빨간색
28+ func recursiveR( _ x: Int , index: Int ) {
29+ if x == r {
30+ recursiveG ( 0 , index: 0 )
31+ return
32+ }
33+
34+ for i in index..< sprinkable. count {
35+ if !isUsed[ i] {
36+ rCombi [ x] = sprinkable [ i]
37+ isUsed [ i] = true
38+ recursiveR ( x+ 1 , index: i+ 1 )
39+ isUsed [ i] = false
40+ }
41+ }
42+ }
43+
44+ // 1. 배양액 뿌릴 수 있는 좌표 탐색 - 초록색
45+ func recursiveG( _ x: Int , index: Int ) {
46+ if x == g {
47+ sprinkle ( rCombi: rCombi, gCombi: gCombi)
48+ result = max ( result, bfs ( ) )
49+ return
50+ }
51+
52+ for i in index..< sprinkable. count {
53+ if !isUsed[ i] {
54+ gCombi [ x] = sprinkable [ i]
55+ isUsed [ i] = true
56+ recursiveG ( x+ 1 , index: i+ 1 )
57+ isUsed [ i] = false
58+ }
59+ }
60+ }
61+
62+ // 2. 해당 좌표에 배양액 뿌리기
63+ func sprinkle( rCombi: [ ( Int , Int ) ] , gCombi: [ ( Int , Int ) ] ) {
64+ vist = Array ( repeating: Array ( repeating: ( " " , 0 ) , count: m) , count: n)
65+ queue = [ ]
66+
67+ for i in 0 ..< rCombi. count {
68+ vist [ rCombi [ i] . 0 ] [ rCombi [ i] . 1 ] . 0 = " R "
69+ vist [ rCombi [ i] . 0 ] [ rCombi [ i] . 1 ] . 1 = 1
70+ queue. append ( rCombi [ i] )
71+ }
72+
73+ for i in 0 ..< gCombi. count {
74+ vist [ gCombi [ i] . 0 ] [ gCombi [ i] . 1 ] . 0 = " G "
75+ vist [ gCombi [ i] . 0 ] [ gCombi [ i] . 1 ] . 1 = 1
76+ queue. append ( gCombi [ i] )
77+ }
78+ }
79+
80+ // 3. 인접한 곳으로 배양액 퍼트리기 -> bfs
81+ func bfs( ) -> Int {
82+ let dx = [ - 1 , 1 , 0 , 0 ]
83+ let dy = [ 0 , 0 , - 1 , 1 ]
84+ var pointer = 0
85+ var count = 0
86+
87+ while pointer < queue. count {
88+ let cur = queue [ pointer]
89+ pointer += 1
90+
91+ if vist [ cur. 0 ] [ cur. 1 ] . 0 == " F " { continue }
92+
93+ for i in 0 ..< 4 {
94+ let curColor = vist [ cur. 0 ] [ cur. 1 ] . 0
95+ let nx = cur. 0 + dx[ i]
96+ let ny = cur. 1 + dy[ i]
97+
98+ if !( 0 ..< n ~= nx) || !( 0 ..< m ~= ny) { continue }
99+ if board [ nx] [ ny] == " 0 " || vist [ nx] [ ny] . 0 == " F " { continue }
100+
101+ if vist [ nx] [ ny] . 0 == " " {
102+ vist [ nx] [ ny] = ( curColor, vist [ cur. 0 ] [ cur. 1 ] . 1 + 1 )
103+ queue. append ( ( nx, ny) )
104+ } else if vist [ nx] [ ny] . 0 == " R " || vist [ nx] [ ny] . 0 == " G " {
105+ if curColor != vist [ nx] [ ny] . 0 && ( vist [ nx] [ ny] . 1 == vist [ cur. 0 ] [ cur. 1 ] . 1 + 1 ) {
106+ count += 1
107+ vist [ nx] [ ny] . 0 = " F "
108+ }
109+ }
110+ }
111+ }
112+ return count
113+ }
0 commit comments