본문 바로가기
알고리즘&자료구조

백준 - 1926(BFS,DFS)

by dongR 2021. 1. 30.

첫 번째 코드)

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Test {
	
	static int n; // 세로크기
	static int m; // 가로크기 
	
	// 상,하,좌,우 (인접한 그림 확인시)
	static int[] X = {-1,1,0,0};
	static int[] Y = {0,0,-1,1};
	
	// 도화지 정보( 그림 - 1 , 그림X - 0)
	static int[][] board;
	
	public static int bfs(int x,int y) {
		int grimSize = 1; // 그림의 크기 
		
		// 큐 자료구조 사용 
		Queue<String> q = new LinkedList<String>();
		String a = "" + x + y; // 정수 -> 문자열 변환
		board[x][y] = 0; // 방문처리 
		q.offer(a); // 큐에 해당 그림의 좌표를 저장 

		// 큐가 비어있지 않을 경우 계속 실행 
		while(!q.isEmpty()) {	
			String q_value = q.poll(); // 큐에서 데이터를 꺼내옴
			// 아스키 코드값 연산 (여기 아스키 코드 연산 부분에서 문제 발생)
			int x1 = (int)q_value.charAt(0) - '0'; // x좌표    
			int y1 = (int)q_value.charAt(1) - '0'; // y좌표 
			
			// 해당 그림의 상하좌우에 인접한 그림이 있는지 검사후 방문하지 않은 그림칸이라면 큐에 넣음 
			for(int i=0;i<4;i++) {
				int x2 = x1 + X[i];
				int y2 = y1 + Y[i];
				// 도화지에 범위 안에 있는지 검사 
				if(0 <= x2 && x2 < n && 0 <= y2 && y2 < m ) {
					// 방문하지 않은 그림칸이면 큐에 넣음(방문한 여부는 0 으로 바꿔줌 )
					if(board[x2][y2] == 1) {
						board[x2][y2] = 0; // 방문처리
						grimSize++; // 그림크기 1 증가 
						q.offer("" + x2 + y2); // 해당 그림칸의 좌표를 큐에 넣음 
					}
				}
			}
		}
		
		return grimSize;
	}
	
	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		n = sc.nextInt(); // 세로크기 
		m = sc.nextInt(); // 가로크기 
		
		// 도화지 정보( 그림 - 1 , 그림X - 0) 입력 
		board = new int[n][m];
		for(int i=0;i<n;i++) {
			for(int j=0;j<m;j++) {
				board[i][j] = sc.nextInt();
			}
		}
		
		// 그림의 개수 구하기 + 크기가 가장 큰 그림의 넓이값 
		// 그림이 저장될 리스트 선언 (각 그림에 대한 넓이 정보가 들어감) 
		ArrayList<Integer> grim = new ArrayList<Integer>();
		// 첫번째 노드부터 시작해서 그림 찾기 
		for(int i=0;i<n;i++) {
			for(int j=0;j<m;j++) {
				// 그림칸일 경우 
				if(board[i][j] == 1) {
					grim.add(bfs(i,j));
				}
			}
		}

		// 가장 큰 그림 넓이 구하기 
		int maxSize = 0; 
		if(grim.size() != 0) {
			for(Integer value : grim) {
				if(value > maxSize) maxSize = value;
			}
		}
		
		System.out.println(grim.size()); // 그림개수
		System.out.println(maxSize); // 가장큰 그림 크기 
	}

}

 

두 번째 코드)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Queue;
import java.util.LinkedList;

public class Test2 {
	
	// 세로,가로 크기 
	static int n;
	static int m;
	// 상,하,좌,우 확인 
	static int[] X = {-1,1,0,0};
	static int[] Y = {0,0,-1,1};
	// 도화지 정보( 그림 - 1 , 그림X - 0)
	static int[][] board;
	// 방문여부 체크( 방문X - 0 , 방문O - 1)
	static int[][] visitedCk;
	// 그림 개수 , 가장 큰 그림 크기 
	static int boardCnt = 0;
	static int maxBoard = 0; 
	
	public static void main(String[] args){
		
		 /*
		 	입력받을 데이터 양이 많으면 하나씩 입력받고 처리하는 것보다 
		 	여러개를 입력받아서 버퍼에 쌓아놓은다음 한꺼번에 처리하는게 성능상 더빠름
		 	
		 	br.readLine() -> 데이터를 라인 단위로 읽음(문자열 단위) 
		 */
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		try {
			String[] nums = br.readLine().split(" ");
			n = Integer.parseInt(nums[0]);
	        m = Integer.parseInt(nums[1]);
	        visitedCk = new int[n][m];
	        board = new int[n][m]; 
	        
	        // 도화지 정보 입력 
	        for(int i=0;i<n;i++) {
	        	// 한행씩 한꺼번에 입력받은 다음 board에 넣어줌 
	        	String[] temp = br.readLine().split(" ");
	        	for(int j=0;j<m;j++) {
	        		board[i][j] = Integer.parseInt(temp[j]);
	        	}
	        }
	        
	        // 이중 for문을 돌면서 그림의 개수와 가장큰 그림 넓이 구하기 
	        for(int i=0;i<n;i++) {
	        	for(int j=0;j<m;j++) {
	        		// 방문을 했거나 그림이 아닐경우 
	        		if(visitedCk[i][j] == 1 || board[i][j] == 0) continue;
	        		
	        		// 그림칸이고 첫방문일 경우 실행 
	        		boardCnt++;
	        		// LinkedList 클래스는 Queue 인터페이스를 구현했기 때문에 Queue 타입으로 받을수 있음 
	        		Queue<Pair<Integer, Integer>> queue = new LinkedList<>();
	        		visitedCk[i][j] = 1; //방문처리 
	        		queue.add(new Pair(i,j)); // 해당 그림칸 좌표의 객체가 큐에 저장 
	        		int area = 0; // 해당 그림의 크기 
	        		
	        		// 큐에 데이터가 없을때까지 반복 
	        		while(!queue.isEmpty()) {
	        			area++;
	        			Pair<Integer, Integer> cur = queue.peek(); // 큐에서 데이터를 꺼내지 않고 읽어옴
	        			//System.out.println("해당 좌표 번지수?" + cur);
	        			queue.poll(); // 큐에서 객체를 꺼내서 반환 
	        			
	        			// 해당 그림의 상하좌우에 인접한 그림이 있는지 검사후 방문하지 않은 그림칸이라면 큐에 넣음 
	        			for(int k=0;k<4;k++) {
	        				int x1 = cur.first + X[k];
	        				int y1 = cur.second + Y[k];
	        				// 도화지의 범위 안에 있는지 검사 
	        				if(x1 < 0 || x1 >= n || y1 < 0 || y1 >= m) continue;
	        				// 방문한 그림칸 여부 + 그림칸인지 검사 
	        				if(visitedCk[x1][y1] == 1 || board[x1][y1] == 0) continue;
	        				visitedCk[x1][y1] = 1; // 해당 그림칸 방문처리 
	        				queue.add(new Pair(x1,y1));
	        			}
	        		}
	        		
	        		// 해당 그림의 크기가 가장 큰 그림인지 검사하는 max 함수 사용 
	        		maxBoard = Math.max(maxBoard,area);
	        	}
	        }
		}catch (IOException e) {
			// 입출력시 예외가 날수도 있기 때문에 예외처리를 꼭 해줘야됨 
			e.printStackTrace();
		}
		
		System.out.println(boardCnt);
		System.out.println(maxBoard);
	}

}

class Pair<I extends Integer, I1 extends Integer> {
    Integer first;
    Integer second;

    public Pair(Integer first, Integer second) {
        this.first = first;
        this.second = second;
    }

    public Integer first() {
        return first;
    }

    public Integer second() {
        return second;
    }
}

- 2~3개의 테스트 케이스가 맞다고 해서 모든 경우가 맞는건 아니다. 

 

 

'알고리즘&자료구조' 카테고리의 다른 글

백준 - 2178(DFS,BFS)  (0) 2021.02.01
정렬(Sort)  (0) 2021.01.30
이코테 - 미로탈출(BFS,DFS)  (0) 2021.01.29
이코테 - 음료수 얼려 먹기(DFS)  (0) 2021.01.27
BFS,DFS  (0) 2021.01.27