백준 3197 : 백조의 호수 (JAVA)

Yu River·2023년 8월 4일
0

코딩테스트 연습

목록 보기
10/11

왜자꾸..메모리 초과가 나오는거니 ? ㅠㅠ

  1. 큐에다가 모든 X를 담고 소거하는 방식으로 풀어서 그런가?
  2. 방문 처리를 제대로 안하고 있나 ? => 그건 아닌듯
  3. 지역 변수를 무분별하게 선언하고 있나 ? => 이것두 아닌듯

이걸 제대로 풀면 다른 문제에도 잘 적용할 수 있겠지 ?

(+) 2023-08-06 수정

드디어 !! '맞았습니다' 가 나왔다 ㅠㅠ

메모리 초과의 원인

BFS할 때 vis 처리를 4회전 반복문 안에다가 해야되는데 그 밖에서 해당 좌표에만 vis 처리를 해버림

정답 소스코드

import java.io.*;
import java.util.*;

public class Main {

	static int r ,c ,day;
	static int[] dx = {0,1,0,-1};
	static int[] dy = {-1,0,1,0};
 	static Queue<Point> q1;	// 물의 좌표
	static Queue<Point> q2;	// 물의 temp 좌표
	static Queue<Point> q3;	// 백조 좌표
	static Queue<Point> q4;	// 백조 temp 좌표
	static Queue<Point> temp_q;
	static boolean[][] vis1,vis2;
	static char[][] mp1;
	
	public static void main(String[] args) throws IOException {
		
		 BufferedReader in  = new BufferedReader(new InputStreamReader(System.in));
		 StringTokenizer st = new StringTokenizer(in.readLine());
		 
		 day = 0;
		 r = Integer.parseInt(st.nextToken());
		 c = Integer.parseInt(st.nextToken());
		 mp1 = new char[r][c];
		 vis1 = new boolean[r][c];
		 vis2 = new boolean[r][c];
		 q1 = new LinkedList();
		 q2 = new LinkedList();
		 q3 = new LinkedList();
		 q4 = new LinkedList();
		 
		 Point l1 = new Point (0,0);
		
		
		//	지도 입력
		 for(int i=0;i<r;i++) {
			 String str1 = in.readLine();
			 for(int j=0;j<str1.length();j++) {
				 mp1[i][j]=str1.charAt(j);
				 if(mp1[i][j]=='L' || mp1[i][j]=='.') {
					 if(mp1[i][j]=='L') {l1.x = j; l1.y = i; }
					 vis1[i][j]=true;
					 q1.add(new Point(j,i));
				 }
			 }
		 }
		// 백조 순회
		 q3.add(new Point(l1.x,l1.y));
		 vis2[l1.y][l1.x]=true;
		// 백조가 서로 만날 때까지 순회를 반복한다.

		while(!func1()) {
			// 백조를 못 만났다면
			func2();
			// 다 녹이면 시간을 하루 늘린다.
			day++;
		}
		
		System.out.print(day);
	}
	
	// func1 : 백조의 순회
	static boolean func1() {
		int cx,cy,nx,ny;
		boolean result = false;
		Point cp;
		while(!q3.isEmpty()) {
			cp = q3.poll();
			cx = cp.x; cy = cp.y;
			for(int i=0;i<4;i++) {
				nx = cx + dx[i]; ny = cy + dy[i];
				if(nx < 0 || nx >= c || ny < 0 || ny >= r || vis2[ny][nx]) continue;
				vis2[ny][nx]=true;
				if(mp1[ny][nx]=='.') {	// 물을 만나면
					q3.add(new Point(nx,ny));	// 다시 순회할 수 있도록 q3에 넣는다.
					//mp1[ny][nx]='1';
				}
				else if(mp1[ny][nx]=='X') {	// 얼음을 만나면
					q4.add(new Point(nx,ny));	// 백조의 temp 좌표에 넣는다.
				}
				else if(mp1[ny][nx]=='L') {	// 백조를 만나면
					result = true;	// true 리턴
					break;
				}
			}
		}
		temp_q = q3;
		q3 = q4;
		q4 = temp_q;
		
		return result;
	}
	
	// func2 : 얼음을 녹임
	static void func2() {
		int cx,cy,nx,ny;
		Point cp;
		while(!q1.isEmpty()) {
			cp = q1.poll();
			cx = cp.x; cy = cp.y;
			for(int i=0;i<4;i++) {
				nx = cx + dx[i]; ny = cy + dy[i];
				if(nx < 0 || nx >= c || ny < 0 || ny >= r || vis1[ny][nx]) continue;
				vis1[ny][nx]=true;
				if(mp1[ny][nx]=='X') {	// 얼음을 만나면
					q2.add(new Point(nx,ny));	// 물의 temp 좌표에 넣는다.
					mp1[ny][nx]='.';	//	녹인다.
				}
			}
		}
		temp_q=q1;
		q1 = q2;
		q2 = temp_q;
	}
	
	static class Point {
		int x,y;
		public Point(int xx, int yy) {
			this.x = xx;
			this.y = yy;
		}
	}
}
profile
도광양회(韜光養晦) ‘빛을 감추고 어둠속에서 힘을 기른다’

1개의 댓글

comment-user-thumbnail
2023년 8월 4일

공감하며 읽었습니다. 좋은 글 감사드립니다.

답글 달기