danbibibi
article thumbnail
Published 2023. 3. 18. 19:23
BOJ 2636번: 치즈 문제 풀이/백준

문제

문제 바로가기> BOJ 2636번: 치즈

 

2636번: 치즈

첫째 줄에는 사각형 모양 판의 세로와 가로의 길이가 양의 정수로 주어진다. 세로와 가로의 길이는 최대 100이다. 판의 각 가로줄의 모양이 윗 줄부터 차례로 둘째 줄부터 마지막 줄까지 주어진

www.acmicpc.net

 

풀이

치즈의 구멍인지, 빈칸인지 확이하기 위해서 4꼭지점에서 BFS 탐색을 시작해 주는게 핵심이다!

 

C++

#include <iostream>
#include <queue>
#define MAX 101
#define EMPTY 0
#define CHEESE 1
using namespace std;

struct POS
{
    int r, c;
};

int R, C;
int total = 0;
int map[MAX][MAX];
bool visited[MAX][MAX];
bool tmp_visisted[MAX][MAX];
int dr[] = {-1, 1, 0, 0};
int dc[] = {0, 0, -1, 1};

void input()
{
    cin >> R >> C;
    for (int i = 0; i < R; i++)
    {
        for (int j = 0; j < C; j++)
        {
            cin >> map[i][j];
            total += map[i][j]; // 치즈 조각이 놓여 있는 칸 수
        }
    }
}

void check_not_cheese(queue<POS> &q)
{
    while (!q.empty())
    {
        int r = q.front().r;
        int c = q.front().c;
        q.pop();

        for (int d = 0; d < 4; d++)
        {
            int nr = r + dr[d];
            int nc = c + dc[d];
            if (nr < 0 || nr >= R || nc < 0 || nc >= C)
                continue;
            if (map[nr][nc] == CHEESE || visited[nr][nc])
                continue;
            visited[nr][nc] = true;
            q.push({nr, nc});
        }
    }
}

void melted_cheese(queue<POS> &q)
{
    for (int i = 0; i < R; i++)
    {
        for (int j = 0; j < C; j++)
            tmp_visisted[i][j] = visited[i][j];
    }

    for (int r = 1; r < R - 1; r++)
    {
        for (int c = 1; c < C - 1; c++)
        {
            if (map[r][c] == EMPTY)
                continue;
            for (int d = 0; d < 4; d++)
            {
                int nr = r + dr[d];
                int nc = c + dc[d];
                if (tmp_visisted[nr][nc])
                {
                    visited[nr][nc] = true;
                    map[r][c] = EMPTY;
                    q.push({nr, nc});
                    break;
                }
            }
        }
    }
}

void solution()
{	
	// 4 꼭짓점에서 BFS 시작
    int sy[] = {0, 0, R - 1, R - 1};
    int sx[] = {0, C - 1, 0, C - 1};

    queue<POS> q;
    for (int i = 0; i < 4; i++)
    {
        q.push({sy[i], sx[i]});
        visited[sy[i]][sx[i]] = true;
    }

    for (int t = 1;; t++)
    {
        check_not_cheese(q);
        melted_cheese(q);
        if (q.size() == total)
        {
            cout << t << "\n"
                 << total;
            return;
        }
        else
            total -= q.size();
    }
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    input();
    if (total)
        solution();
    else
        cout << 0 << "\n"
             << 0;
}

 

JAVA

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

public class Main {
	
	static final int[] dy = {-1,1,0,0};
	static final int[] dx = {0,0,-1,1};
	
	static int R, C;
	static int cheeseCnt= 0;
	static boolean[][] map, visited;
	static ArrayDeque<int[]> q = new ArrayDeque<>();
	
	private static int solution() {
		int res = 0; // 녹은 치즈
		visited = new boolean[R][C];
		ArrayDeque<int[]> next = new ArrayDeque<>();
		
		while(!q.isEmpty()) {
			int y = q.peek()[0];
			int x = q.peek()[1];
			q.poll();
			
			for(int d=0; d<4; d++) {
				int ny = y+dy[d];
				int nx = x+dx[d];
				if(ny<0 || ny>=R || nx<0 || nx>=C || visited[ny][nx]) continue;
				visited[ny][nx] = true;
				if(map[ny][nx]) { // cheese
					map[ny][nx] = false;
					next.offer(new int[] {ny, nx});
					res++;
				}
				else q.offer(new int[] {ny, nx});
			}
		}
		q = next;
		return res;
	}

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		// input
		R = Integer.parseInt(st.nextToken());
		C = Integer.parseInt(st.nextToken());
		map = new boolean[R][C];
		
		for(int i=0; i<R; i++) {
			st = new StringTokenizer(br.readLine());
			for(int j=0; j<C; j++) {
				map[i][j] = (Integer.parseInt(st.nextToken())==0?false:true);
				if(map[i][j]) cheeseCnt++;
			}
		}

		// solution: 가장 자리에서 시작
		q.offer(new int[] {0, 0});
		q.offer(new int[] {0, C-1});
		q.offer(new int[] {R-1, 0});
		q.offer(new int[] {R-1, C-1});
		
		int meltTime=0, lastPiece=0;
		while(true) {
			if(cheeseCnt==0) break;
			cheeseCnt-=solution();
			lastPiece = q.size();
			meltTime++;
		}
		
		// output
		System.out.println(meltTime);
		System.out.println(lastPiece);
	}
}

'문제 풀이 > 백준' 카테고리의 다른 글

BOJ 2623번: 음악프로그램  (0) 2023.03.21
BOJ 1584번: 게임  (0) 2023.03.18
BOJ 2842번 : 집배원 한상덕  (0) 2023.03.10
BOJ 1918번: 후위 표기식  (0) 2023.03.07
BOJ 21758번: 꿀 따기  (0) 2023.02.25
profile

danbibibi

@danbibibi

꿈을 꾸는 시간은 멈춰 있는 것이 아냐 두려워하지 마 멈추지 마 푸른 꿈속으로