1+ package org .example ._50week ;
2+
3+ import java .io .BufferedReader ;
4+ import java .io .IOException ;
5+ import java .io .InputStreamReader ;
6+ import java .util .*;
7+
8+ public class TheSwanLake {
9+
10+ private static final BufferedReader br = new BufferedReader (new InputStreamReader (System .in ));
11+
12+ private static final int WATER = 0 ;
13+ private static final int ICE = 1 ;
14+ private static final int SWAN = 2 ;
15+
16+ private static final int [] dr = {-1 , 0 , 1 , 0 };
17+ private static final int [] dc = {0 , 1 , 0 , -1 };
18+
19+ private static int rowSize ;
20+ private static int colSize ;
21+ private static int [][] map ;
22+ private static int [][] group ;
23+ private static Queue <int []> melts ;
24+ private static Queue <int []> nextMelts ;
25+ private static final List <Integer > swanGroups = new ArrayList <>();
26+ private static final Map <Integer , Integer > parent = new HashMap <>();
27+
28+ public static void main (String [] args ) throws IOException {
29+ input ();
30+
31+ int groupNo = 3 ;
32+ for (int row = 0 ; row < rowSize ; row ++) {
33+ for (int col = 0 ; col < colSize ; col ++) {
34+ if (map [row ][col ] != ICE && group [row ][col ] == 0 ) { // WATER, SWAN
35+ markGroup (row , col , groupNo );
36+ groupNo ++;
37+ }
38+ }
39+ }
40+
41+ // 처음에 바로 만나있으면
42+ // sout 0
43+ Integer firstSwanGroup = swanGroups .get (0 );
44+ Integer secondSwanGroup = swanGroups .get (1 );
45+ if (firstSwanGroup .equals (secondSwanGroup )) {
46+ System .out .println (0 );
47+ }
48+
49+ // 1일차.
50+ for (int row = 0 ; row < rowSize ; row ++) {
51+ for (int col = 0 ; col < colSize ; col ++) {
52+ if (map [row ][col ] == ICE ) {
53+ boolean isConnected = melt (row , col );
54+ if (isConnected ) {
55+ System .out .println (1 );
56+ return ;
57+ }
58+ }
59+ }
60+ }
61+
62+ for (int [] melt : melts ) {
63+ map [melt [0 ]][melt [1 ]] = WATER ;
64+ }
65+
66+ for (int day = 2 ; ; day ++) {
67+ melts = nextMelts ;
68+ nextMelts = new LinkedList <>();
69+
70+ for (int [] melt : melts ) {
71+ int row = melt [0 ];
72+ int col = melt [1 ];
73+
74+ if (map [row ][col ] == ICE ) {
75+ boolean isConnected = melt (row , col );
76+ if (isConnected ) {
77+ System .out .println (day );
78+ return ;
79+ }
80+ }
81+ }
82+
83+ for (int [] melt : melts ) {
84+ map [melt [0 ]][melt [1 ]] = WATER ;
85+ }
86+ }
87+ }
88+
89+ private static boolean melt (int row , int col ) {
90+ for (int i = 0 ; i < 4 ; i ++) {
91+ int nextRow = row + dr [i ];
92+ int nextCol = col + dc [i ];
93+
94+ if (nextRow < 0 || nextRow >= rowSize || nextCol < 0 || nextCol >= colSize ) {
95+ continue ;
96+ }
97+
98+ if (map [nextRow ][nextCol ] == ICE ) {
99+ continue ;
100+ }
101+
102+ melts .add (new int []{row , col });
103+ group [row ][col ] = group [nextRow ][nextCol ];
104+ }
105+
106+ if (group [row ][col ] == 0 ) {
107+ return false ;
108+ }
109+
110+ for (int i = 0 ; i < 4 ; i ++) {
111+ int nextRow = row + dr [i ];
112+ int nextCol = col + dc [i ];
113+
114+ if (nextRow < 0 || nextRow >= rowSize || nextCol < 0 || nextCol >= colSize ) {
115+ continue ;
116+ }
117+
118+ int adjacent = group [nextRow ][nextCol ];
119+ if (adjacent == 0 ) {
120+ nextMelts .add (new int []{nextRow , nextCol });
121+ continue ;
122+ }
123+
124+ if (group [row ][col ] == adjacent ) {
125+ continue ;
126+ }
127+
128+ union (group [row ][col ], adjacent );
129+
130+ Integer firstSwanGroup = swanGroups .get (0 );
131+ Integer secondSwanGroup = swanGroups .get (1 );
132+ if (isSame (firstSwanGroup , secondSwanGroup )) {
133+ return true ;
134+ }
135+ }
136+
137+ return false ;
138+ }
139+
140+ private static void union (int first , int second ) {
141+ if (first == 0 ) {
142+ parent .put (first , second );
143+ return ;
144+ } else if (second == 0 ) {
145+ parent .put (second , first );
146+ return ;
147+ }
148+
149+ int firstParent = find (first );
150+ int secondParent = find (second );
151+
152+ if (firstParent <= secondParent ) {
153+ parent .put (secondParent , firstParent );
154+ } else {
155+ parent .put (firstParent , secondParent );
156+ }
157+ }
158+
159+ private static boolean isSame (int first , int second ) {
160+ int firstParent = find (first );
161+ int secondParent = find (second );
162+
163+ return firstParent == secondParent ;
164+ }
165+
166+ private static int find (int unit ) {
167+ if (parent .get (unit ) == unit ) {
168+ return unit ;
169+ }
170+
171+ int p = parent .get (parent .get (unit ));
172+ parent .put (unit , p );
173+
174+ return p ;
175+ }
176+
177+ private static void markGroup (int row , int col , int groupNo ) {
178+ // 진영 선택
179+ // 백조 진영 확인
180+ // union find 배열도 만들어줘야함.
181+ parent .put (groupNo , groupNo );
182+
183+ Queue <int []> queue = new LinkedList <>();
184+ queue .add (new int []{row , col });
185+ group [row ][col ] = groupNo ;
186+
187+ while (!queue .isEmpty ()) {
188+ int [] pos = queue .poll ();
189+ int curRow = pos [0 ];
190+ int curCol = pos [1 ];
191+ group [curRow ][curCol ] = groupNo ;
192+
193+ if (map [curRow ][curCol ] == SWAN ) {
194+ swanGroups .add (groupNo );
195+ }
196+
197+ for (int i = 0 ; i < 4 ; i ++) {
198+ int nextRow = curRow + dr [i ];
199+ int nextCol = curCol + dc [i ];
200+
201+ if (nextRow < 0 || nextRow >= rowSize || nextCol < 0 || nextCol >= colSize ) {
202+ continue ;
203+ }
204+
205+ if (map [nextRow ][nextCol ] == ICE ) {
206+ continue ;
207+ }
208+
209+ if (group [nextRow ][nextCol ] != 0 ) {
210+ continue ;
211+ }
212+
213+ group [nextRow ][nextCol ] = groupNo ;
214+ queue .add (new int []{nextRow , nextCol });
215+ }
216+ }
217+ }
218+
219+ private static void input () throws IOException {
220+ StringTokenizer st = new StringTokenizer (br .readLine ());
221+ rowSize = Integer .parseInt (st .nextToken ());
222+ colSize = Integer .parseInt (st .nextToken ());
223+
224+ map = new int [rowSize ][colSize ];
225+ group = new int [rowSize ][colSize ];
226+ // melts = new boolean[rowSize][colSize];
227+ melts = new LinkedList <>();
228+ nextMelts = new LinkedList <>();
229+
230+ for (int row = 0 ; row < rowSize ; row ++) {
231+ String input = br .readLine ();
232+
233+ for (int col = 0 ; col < colSize ; col ++) {
234+ char cell = input .charAt (col );
235+ if (cell == 'X' ) {
236+ map [row ][col ] = ICE ;
237+ } else if (cell == '.' ) {
238+ map [row ][col ] = WATER ;
239+ } else {
240+ map [row ][col ] = SWAN ;
241+ }
242+ }
243+ }
244+ }
245+ }
0 commit comments