Skip to content

Conversation

@wnsmir
Copy link
Collaborator

@wnsmir wnsmir commented Jul 31, 2025

πŸ”— 문제 링크

https://school.programmers.co.kr/learn/courses/30/lessons/388353

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

30min

✨ μˆ˜λ„ μ½”λ“œ

μ–Όλ§ˆμ „ μΉ˜μ¦ˆλ¬Έμ œμ˜€λ‚˜μš”?
ꡉμž₯히 λΉ„μŠ·ν•΄μ„œ κΈˆλ°©ν’€ 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

λ‹€λ§Œ κ·Έλ¬Έμ œμ™€ λ‹€λ₯Έμ μ€ μ΄λ¬Έμ œλŠ” νƒœλ‘λ¦¬κ°€ μ—†λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€...γ…œ
κ·Έλž˜μ„œ 직접 νŒ¨λ”©ν•΄μ£Όμ–΄ 각 λͺ…λ Ήμ–΄λ§ˆλ‹€ bfsλ₯Ό μˆ˜ν–‰ν•΄ μ™ΈλΆ€λ₯Ό 0으둜 λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€.

치즈문제둜 치면 외뢀곡기가 0μ΄λ˜λŠ”κ²ƒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

각 λͺ…령문을 돌며 μ•ŒνŒŒλ²³μ΄ λ‘κ°œλ‚˜μ˜€λ©΄ κ·Έλƒ₯ 반볡문 λ‘λ²ˆ λŒλ©΄μ„œ 1둜 λ°”κΏ”μ£Όκ³ , 1은 λ‹€μ‹œ bfsλ₯Ό 톡해 외뢀와 μ ‘μ΄‰ν•˜λŠ” 1은 0으둜 λ§Œλ“€μ–΄μ€λ‹ˆλ‹€.

λ‹€λ§Œ 살짝 ν–‡κ°ˆλ Έλ˜ 뢀뢄이 μžˆμ—ˆλ‹€λ©΄, μ§€κ²Œμ°¨λ‘œμ§μ˜ 뒀에도 bfsλ₯Ό 달아주어야 ν•©λ‹ˆλ‹€.
ν¬λ ˆμΈμ€ λ‹Ήμ—°νžˆ 1둜 바꾸어쀬닀가 κ·Έ 1이 0κ³Ό λΆ™μ–΄μžˆλ‹€λ©΄ 0으둜 λ°”κΏ”μ£ΌλŠ” bfsκ°€ ν•„μš”ν•˜λ‹€λ©΄,

μ§€κ²Œμ°¨λ„ λ§Œμ•½ 외뢀와 λΆ™μ–΄μžˆλŠ” 짐을 없앴을떄 내뢀에 1이 μžˆμ—ˆλ‹€λ©΄ κ·Έ 1을 λ‹€λ₯Έ λͺ…λ Ήμ–΄κ°€ μ‹€ν–‰λ˜κΈ°μ „μ— 0으둜 λ°”κΏ”μ€˜μ•Όν•˜κΈ° λ–„λ¬Έμž…λ‹ˆλ‹€.

즉 μ§€κ²Œμ°¨λ“  ν¬λ ˆμΈμ΄λ“  각 둜직이 λλ‚˜κ³  bfs둜 μ™ΈλΆ€μ™€μ˜ 접촉을 항상 μ—…λ°μ΄νŠΈν•΄μ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€.

from collections import deque

def solution(storage, requests):
    n = len(storage)
    m = len(storage[0])

    # 0 νŒ¨λ”©
    grid = [[0] * (m+2)]
    for row in storage:
        grid.append([0] + list(row) + [0])
    grid.append([0] * (m+2))

    dx = [1, -1, 0, 0]
    dy = [0, 0, 1, -1]

    def bfs():
        visited = [[False] * (m+2) for _ in range(n+2)]
        queue = deque()
        queue.append((0, 0))
        visited[0][0] = True
        while queue:
            x, y = queue.popleft()
            for i in range(4):
                nx = x + dx[i]
                ny = y + dy[i]
                if 0 <= nx < n+2 and 0 <= ny < m+2 and not visited[nx][ny]:
                    if grid[nx][ny] in (0, 1):
                        visited[nx][ny] = True
                        if grid[nx][ny] == 1:
                            grid[nx][ny] = 0
                        queue.append((nx, ny))
    
    for request in requests:
        selected = []

        # 크레인
        if len(request) == 2:
            target = request[0]
            for x in range(1, n+1):
                for y in range(1, m+1):
                    if grid[x][y] == target:
                        selected.append((x, y))

            for x, y in selected:
                grid[x][y] = 1
            
            bfs()

        # μ§€κ²Œμ°¨
        elif len(request) == 1:
            target = request
            for i in range(1, n + 1):
                for j in range(1, m + 1):
                    if grid[i][j] == target:
                        for d in range(4):
                            ni = i + dx[d]
                            nj = j + dy[d]
                            if grid[ni][nj] == 0:
                                selected.append((i, j))
                                break
            for x, y in selected:
                grid[x][y] = 0
            bfs()

    # 남은물건 개수
    count = 0
    for i in range(1, n + 1):
        for j in range(1, m + 1):
            if grid[i][j] not in (0, 1):
                count += 1

    return count

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

Copy link
Member

@9kyo-hwang 9kyo-hwang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3μ›”μ˜ 와타사기 μ›νŠΈν΄μ„ ν•΄λ†¨κ΅°μš”(λΏŒλ“―)
image

μ €λŠ” λ¬Έμžμ—΄ λ°°μ—΄λ‘œ μ£Όμ–΄μ§€λŠ” storage 정보λ₯Ό νŒ¨λ”©μ‹œν‚¨ int 2차원 λ°°μ—΄λ‘œ λ‹€ λ§€ν•‘μ‹œμΌ°μŠ΅λ‹ˆλ‹€. 그리고 '확인 μ™„λ£Œλœ μΉΈ'은 -1둜 λ‘μ—ˆμŠ΅λ‹ˆλ‹€.

int N, M;
vector<vector<int>> GStorage;

int solution(vector<string> Storage, vector<string> Requests) 
{
    N = Storage.size(); M = Storage[0].size();
    GStorage.assign(N + 2, vector<int>(M + 2, -1));  // 기본값은 -1
    
    for(int i = 1; i <= N; ++i)
    {
        for(int j = 1; j <= M; ++j)
        {
            GStorage[i][j] = Storage[i - 1][j - 1] - 'A';  // A ~ Zλ₯Ό 0 ~ 25둜 λŒ€μ‘
        }
    }
    
    ...
}

그리고 requestλ₯Ό ν™•μΈν•˜λ©΄μ„œ 길이가 1이면 μ§€κ²Œμ°¨, 2라면 ν¬λ ˆμΈμ„ μ‚¬μš©ν•˜λŠ” μš”μ²­μ„ μˆ˜ν–‰ν•˜λ„λ‘ ν–ˆμŠ΅λ‹ˆλ‹€. 이 λ•Œ 졜초 Answer λ³€μˆ˜ 값을 Storage 크기둜 μ΄ˆκΈ°ν™”ν•œ λ’€, 각 μš”μ²­μ—μ„œ 'κΊΌλ‚Έ μ»¨ν…Œμ΄λ„ˆ 개수'λ₯Ό λ°˜ν™˜ν•˜κ²Œ ν•΄μ„œ 이λ₯Ό 계속 λΉΌλŠ” μ‹μœΌλ‘œ μ²˜λ¦¬ν–ˆμŠ΅λ‹ˆλ‹€. 이러면 μžμ—°μŠ€λŸ½κ²Œ μš”μ²­μ΄ μ’…λ£Œλ˜λ©΄ '남은 μ»¨ν…Œμ΄λ„ˆ 개수'λ₯Ό μ¦‰μ‹œ λ°˜ν™˜ν•  수 있기 λ•Œλ¬Έμ΄μ£ .

int solution(vector<string> Storage, vector<string> Requests) 
{
    ...
    
    int Answer = N * M;
    
    for(const string& Request : Requests)
    {
        if(Request.length() == 1)
        {
            Answer -= DeliveryByForklift(Request[0] - 'A');
        }
        else
        {
            Answer -= DeliveryByCrane(Request[0] - 'A');
        }
    }
    
    return Answer;
}

μ§€κ²Œμ°¨ μ‚¬μš©ν•˜λŠ” 건 μ–ΈκΈ‰ν•˜μ‹  λŒ€λ‘œ 치즈 문제 ν‘Ό 것과 거의 λ™μΌν•˜κ²Œ ν•΄κ²°ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 단 순회λ₯Ό μ§„ν–‰ν•  λ•Œ

  1. 인접칸이 μ°ΎλŠ” μ»¨ν…Œμ΄λ„ˆλΌλ©΄ 개수λ₯Ό μΉ΄μš΄νŒ…ν•˜κ³  더 이상 μ ‘κ·Όν•˜μ§€ λͺ»ν•˜λ„둝 storage 배열에 -1을 λ§ˆν‚Ήν•˜κΈ°
  2. μ»¨ν…Œμ΄λ„ˆκ°€ κΊΌλ‚΄μ§„ 칸이라면 λ‹€μŒ μˆœνšŒλ•Œ 탐색할 ν›„λ³΄λ‘œ μ§€μ •

이 두 κ°€μ§€λ₯Ό 적절히 μˆ˜ν–‰ν•˜λŠ” 게 ν‚€μ˜€λ˜ 것 κ°™μŠ΅λ‹ˆλ‹€.

const vector<pair<int, int>> Offset
{
    {-1, 0},
    {0, 1},
    {1, 0},
    {0, -1}
};

bool OutOfBound(int x, int y)
{
    return !(0 <= x && x <= N + 1 && 0 <= y && y <= M + 1);
}

int DeliveryByForklift(const int Container)
{
    int NumDelivery = 0;
    
    queue<pair<int, int>> Q;
    Q.emplace(0, 0);
    
    vector<vector<bool>> Visited(N + 2, vector<bool>(M + 2, false));
    Visited[0][0] = true;
    
    while(!Q.empty())
    {
        const auto [x, y] = Q.front();
        Q.pop();
        
        for(const auto& [dx, dy] : Offset)
        {
            int nx = x + dx, ny = y + dy;
            if(OutOfBound(nx, ny) || Visited[nx][ny])
            {
                continue;
            }
            
            Visited[nx][ny] = true;
            if(GStorage[nx][ny] == Container)  // μ°ΎλŠ” μ»¨ν…Œμ΄λ„ˆλΌλ©΄
            {
                NumDelivery++;
                GStorage[nx][ny] = -1;  // κΊΌλ‚΄κΈ°
            }
            else if(GStorage[nx][ny] == -1)  // 이미 κΊΌλ‚΄μ§„ 칸이라면
            {
                Q.emplace(nx, ny);  // λ‹€μŒ μˆœνšŒλ•Œ 확인해야 ν•  μΉΈ
            }
        }
    }
    
    return NumDelivery;
}

이런 μ‹μœΌλ‘œ μ²˜λ¦¬ν•˜λ©΄ ν¬λ ˆμΈμ—μ„œλŠ” κ·Έλƒ₯ 2쀑 반볡문 μˆœνšŒν•˜λ©΄μ„œ ν•΄λ‹Ή μ»¨ν…Œμ΄λ„ˆ 칸만 μ²˜λ¦¬ν•΄μ£Όλ©΄ λ©λ‹ˆλ‹€.

int DeliveryByCrane(const int Container)
{
    int NumDelivery = 0;
    for(int i = 1; i <= N; ++i)
    {
        for(int j = 1; j <= M; ++j)
        {
            if(GStorage[i][j] == Container)
            {
                GStorage[i][j] = -1;
                NumDelivery++;
            }
        }
    }
    
    return NumDelivery;
}
전체 μ½”λ“œ

#include <string>
#include <vector>
#include <queue>

using namespace std;

int N, M;
vector<vector<int>> GStorage;
const vector<pair<int, int>> Offset
{
    {-1, 0},
    {0, 1},
    {1, 0},
    {0, -1}
};

bool OutOfBound(int x, int y)
{
    return !(0 <= x && x <= N + 1 && 0 <= y && y <= M + 1);
}

int DeliveryByForklift(const int Container)
{
    int NumDelivery = 0;
    
    queue<pair<int, int>> Q;
    Q.emplace(0, 0);
    
    vector<vector<bool>> Visited(N + 2, vector<bool>(M + 2, false));
    Visited[0][0] = true;
    
    while(!Q.empty())
    {
        const auto [x, y] = Q.front();
        Q.pop();
        
        for(const auto& [dx, dy] : Offset)
        {
            int nx = x + dx, ny = y + dy;
            if(OutOfBound(nx, ny) || Visited[nx][ny])
            {
                continue;
            }
            
            Visited[nx][ny] = true;
            if(GStorage[nx][ny] == Container)
            {
                NumDelivery++;
                GStorage[nx][ny] = -1;
            }
            else if(GStorage[nx][ny] == -1)
            {
                Q.emplace(nx, ny);
            }
        }
    }
    
    return NumDelivery;
}

int DeliveryByCrane(const int Container)
{
    int NumDelivery = 0;
    for(int i = 1; i <= N; ++i)
    {
        for(int j = 1; j <= M; ++j)
        {
            if(GStorage[i][j] == Container)
            {
                GStorage[i][j] = -1;
                NumDelivery++;
            }
        }
    }
    
    return NumDelivery;
}

int solution(vector<string> Storage, vector<string> Requests) 
{
    N = Storage.size(); M = Storage[0].size();
    GStorage.assign(N + 2, vector<int>(M + 2, -1));
    
    for(int i = 1; i <= N; ++i)
    {
        for(int j = 1; j <= M; ++j)
        {
            GStorage[i][j] = Storage[i - 1][j - 1] - 'A';
        }
    }
    
    int Answer = N * M;
    
    for(const string& Request : Requests)
    {
        if(Request.length() == 1)
        {
            Answer -= DeliveryByForklift(Request[0] - 'A');
        }
        else
        {
            Answer -= DeliveryByCrane(Request[0] - 'A');
        }
    }
    
    return Answer;
}

@wnsmir
Copy link
Collaborator Author

wnsmir commented Aug 1, 2025

νŒ¨λ”© 말고 λ‹€λ₯Έ 방법이 μžˆμ„κΉŒ μž μ‹œ κ³ λ―Όν–ˆλŠ”λ° μ‹€μ „μ΄μ—ˆλ‹€λ©΄ λ§μ„€μž„ 없이 νŒ¨λ”©μ„ 썼을 것 κ°™λ”λΌκ³ μš”,, κ²°κ΅­ νŒ¨λ”©μœΌλ‘œ ν’€μ—ˆλŠ”λ°, 같은 λ°©μ‹μœΌλ‘œ ν‘Έμ…¨λ„€μš”!

Copy link
Collaborator

@kangrae-jo kangrae-jo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μž¬λ°ŒλŠ” λ¬Έμ œλ„€μš”.
μ˜ˆμ „μ— ν’€μ—ˆλ˜κ²ƒ 같기도 ν•©λ‹ˆλ‹€.

μ €λŠ” νŒ¨λ”©μ„ ν•˜μ§€μ•Šκ³  ν’€μ—ˆμŠ΅λ‹ˆλ‹€.
λ§Œμ•½ λ‹€μŒμœΌλ‘œ 이동할 boardκ°€ λΉ„μ–΄μžˆκ±°λ‚˜, λ°©λ¬Έλ˜μ§€ μ•Šμ•˜μ„ κ²½μš°μ—λ§Œ 큐에 λ„£κ³ ,
νμ—μ„œ κΊΌλ‚΄μ—ˆμ„ λ•Œ κ°€μž₯자리면 trueλ₯Ό λ°˜ν™˜ν•˜λŠ” μ‹μœΌλ‘œ 체크λ₯Ό ν–ˆμ–΄μš”.

그리고 또 ν•œκ°€μ§€ μ£Όμ˜ν•  점이라면,
μ§€κ²Œμ°¨λ‘œ μ•ŒνŒŒλ²³μ„ μ§€μšΈλ•Œ, λ”± κ·Έ μ‹œμ μ—μ„œ μ§€κ²Œμ°¨λ‘œ κΊΌλ‚Ό 수 μžˆλŠ” λ…€μ„λ“€λ§Œ κΊΌλ‚΄μ•Ό ν•œλ‹€λŠ” μ μ΄μ—ˆλ˜ 것 κ°™μ•„μš”.

예λ₯Ό λ“€μ–΄ Aν•˜λ‚˜κ°€ μΉ˜μ›Œμ§€λ©΄ κ·Έμ•ˆμ— Aλ₯Ό κΊΌλ‚Όμˆ˜ μžˆλŠ” 상황은... λ¬Έμ œμ—μ„œ μš”κ΅¬ν•˜λŠ” λ°”κ°€ μ•„λ‹Œκ±°μ£ .
μ €λŠ” κ·Έλž˜μ„œ κΊΌλ‚Όμˆ˜ μžˆλŠ” λ…€μ„λ“€μ˜ μ’Œν‘œλ₯Ό μ €μž₯해놓고 각 쿼리의 λ§ˆμ§€λ§‰μ— μ²˜λ¦¬ν•΄μ£Όμ—ˆμŠ΅λ‹ˆλ‹€.

μ’‹μ€λ¬Έμ œ κ°μ‚¬ν•©λ‹ˆλ‹€.

#include <string>
#include <vector>
#include <queue>

using namespace std;

const int EMPTY = 0;
const int OFFSET[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

int n, m;
vector<vector<int>> board;

bool isIn(int y, int x) { return 0 <= y && y < n && 0 <= x && x < m; }
bool isOutLine(int y, int x) { return y == 0 || y == n - 1 || x == 0 || x == m - 1; }

bool canRemove(int y, int x, int c){
    vector<vector<bool>> visited(n, vector<bool> (m, false));
    
    queue<pair<int, int>> q;
    q.push({y, x});
    visited[y][x] = true;
    
    while (!q.empty()) {
        auto [curY, curX] = q.front();
        q.pop();
        
        if (isOutLine(curY, curX)) return true;
        
        for (int dir = 0; dir < 4; dir++) {
            int nextY = curY + OFFSET[dir][0];
            int nextX = curX + OFFSET[dir][1];
            
            if (isIn(nextY, nextX) && board[nextY][nextX] == EMPTY && !visited[nextY][nextX]) {
                q.push({nextY, nextX});
                visited[nextY][nextX] = true;
            }
        }
    }
    
    return false;
}

int solution(vector<string> storage, vector<string> requests) {
    n = storage.size();
    m = storage[0].size();
    
    board = vector<vector<int>> (n, vector<int> (m));
    for (int y = 0; y < n; y++) {
        for (int x = 0; x < m; x++) {
            board[y][x] = storage[y][x];
        }
    }
    
    for (string request : requests) {
        int c = request[0];
        
        if (request.size() == 2) { // all
            for (int y = 0; y < n; y++) {
                for (int x = 0; x < m; x++) {
                    if (board[y][x] == c) board[y][x] = EMPTY;
                }
            }
        } else { // outline
            vector<pair<int, int>> result;
            for (int y = 0; y < n; y++) {   
                for (int x = 0; x < m; x++) {
                    if (board[y][x] == c && canRemove(y, x, c)) result.push_back({y, x});
                }
            }
    
            for (auto [y, x] : result) board[y][x] = EMPTY;
        }
    }
    
    int answer = 0;
    for (int y = 0; y < n; y++) {
        for (int x = 0; x < m; x++) {
            if (board[y][x] != EMPTY) answer++;
        }
    }
        
    return answer;
}

@kangrae-jo
Copy link
Collaborator

kangrae-jo commented Aug 2, 2025

μ˜ˆμ „μ— ν’€μ—ˆλ˜ κΈ°μ–΅μœΌλ‘œ λ‚ λ¨Ήν•œ 것 κ°™μ•„μ„œ μžλ°”λ‘œλ„ ν•΄λ΄€μŠ΅λ‹ˆλ‹€.

μžλ°”λŠ” μŠ€νŠΈλ§μ„ λ‹€λ£¨κΈ°κΉŒλ‹€λ‘œμ›Œμ„œ char[][]둜 λ³€ν™˜ν•œ λ’€ λ™μΌν•œ 둜직으둜 문제λ₯Ό ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€.

Java Code
import java.util.*;

class Solution {

    static final int[][] OFFSET = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
    static int n, m;

    public int solution(String[] storage, String[] requests) {
        n = storage.length;
        m = storage[0].length();

        char[][] board = new char[n][m];
        for (int i = 0; i < n; i++) {
            board[i] = storage[i].toCharArray();
        }

        for (String request : requests) {
            char c = request.charAt(0);

            // 크레인
            if (request.length() == 2) {
                for (int y = 0; y < n; y++) {
                    for (int x = 0; x < m; x++) {
                        if (board[y][x] == c) {
                            board[y][x] = '0';
                        }
                    }
                }
            }
            // μ§€κ²Œμ°¨
            else {
                Queue<Pos> q = new LinkedList<>();
                for (int y = 0; y < n; y++) {
                    for (int x = 0; x < m; x++) {
                        if (board[y][x] == c && canRemove(board, y, x)) {
                            q.add(new Pos(y, x));
                        }
                    }
                }

                while (!q.isEmpty()) {
                    Pos p = q.poll();
                    board[p.y][p.x] = '0';
                }
            }
        }

        int answer = 0;
        for (int y = 0; y < n; y++) {
            for (int x = 0; x < m; x++) {
                if (board[y][x] != '0') answer++;
            }
        }

        return answer;
    }

    private static boolean canRemove(char[][] board, int y, int x) {
        boolean[][] visited = new boolean[n][m];
        Queue<Pos> q = new LinkedList<>();
        q.add(new Pos(y, x));
        visited[y][x] = true;

        while (!q.isEmpty()) {
            Pos cur = q.poll();

            if (isOutLine(cur.y, cur.x)) return true;

            for (int dir = 0; dir < 4; dir++) {
                int nextY = cur.y + OFFSET[dir][0];
                int nextX = cur.x + OFFSET[dir][1];
                if (isIn(nextY, nextX) && !visited[nextY][nextX] && board[nextY][nextX] == '0') {
                    q.add(new Pos(nextY, nextX));
                    visited[nextY][nextX] = true;
                }
            }
        }

        return false;
    }

    private static boolean isOutLine(int y, int x) {
        return y == 0 || y == n - 1 || x == 0 || x == m - 1;
    }

    private static boolean isIn(int y, int x) {
        return 0 <= y && y < n && 0 <= x && x < m;
    }

    private static class Pos {
        int y, x;

        public Pos(int y, int x) {
            this.y = y;
            this.x = x;
        }
    }

}

Copy link
Collaborator

@kokeunho kokeunho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 νŒ¨λ”© μ²˜λ¦¬ν•˜μ—¬ map을 λ‹€μ‹œ κ΅¬μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

그리고 request의 길이가 2, 1둜 λ‚˜λˆ„μ–΄
1이면 (0, 0)μ—μ„œ bfsλ₯Ό μ‹œμž‘ν•˜μ—¬ 외뢀와 μ ‘μ΄‰λœ μ»¨ν…Œμ΄λ„ˆ 쀑 requestν•΄ ν•΄λ‹Ήν•˜λŠ” charλ₯Ό μ œκ±°ν•˜μ˜€μŠ΅λ‹ˆλ‹€.
2라면 전체 mapμ—μ„œ request에 ν•΄λ‹Ήν•˜λŠ” chλ₯Ό λͺ¨λ‘ μ œκ±°ν•΄μ£Όμ—ˆμŠ΅λ‹ˆλ‹€.

μˆ˜κ³ ν•˜μ…¨μŠ΅λ‹ˆλ‹€.

Details

import java.util.*;

class Solution {
    static char[][] map;
    static int[] dx = {-1, 1, 0, 0};
    static int[] dy = {0, 0, -1, 1};
    
    public int solution(String[] storage, String[] requests) {
        map = new char[storage.length+2][storage[0].length()+2];
        
        for (int i = 0; i < map.length; i++) {
            Arrays.fill(map[i], '-');
        }
        
        for (int i = 0; i < storage.length; i++) {
            String line = storage[i];
            for (int j = 0; j < line.length(); j++) {
                map[i+1][j+1] = line.charAt(j);               
            }
        }
        
        processReq(requests);
        
        return countContainer();
    }
    void processReq(String[] requests) {
        for (String request : requests) {
            char ch = request.charAt(0);
            if (request.length() == 1) {
                bfs(0, 0, ch);
            } else {
                removeCh(ch);
            }
        }
    }
    void bfs(int x, int y, char ch) {
        Queue<int[]> queue = new LinkedList<>();
        boolean[][] visited = new boolean[map.length][map[0].length];
        queue.add(new int[]{x, y});
        visited[x][y] = true;
        
        while(!queue.isEmpty()) {
            int[] current = queue.poll();
            for (int i = 0; i < 4; i++) {
                int nx = current[0] + dx[i];
                int ny = current[1] + dy[i];
                if (nx >= 0 && nx < map.length && ny >= 0 && ny < map[0].length && !visited[nx][ny]) {
                    if (map[nx][ny] == '-') {
                        queue.add(new int[]{nx, ny});
                        visited[nx][ny] = true;
                    } 
                    if (map[nx][ny] == ch) {
                        map[nx][ny] = '-';
                        visited[nx][ny] = true;
                    }
                }
            }
        }
    }
    void removeCh(char ch) {
        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map[0].length; j++) {
                if (map[i][j] == ch) {
                    map[i][j] = '-';
                }
            }
        }
    }
    int countContainer() {
        int count = 0;
        
        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map[0].length; j++) {
                if (map[i][j] != '-') count++;
            }
        }
        return count;
    }

}

Copy link
Collaborator

@g0rnn g0rnn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

νŒŒμ΄μ¬μ€ μ–΄λ ΅κ΅°μš”...γ…‹γ…‹γ…‹ 적응이 μ•ˆλ˜λ„€μš”. 저도 νŒ¨λ”©μ„ λ„£κ³  μ™Έκ³½μ—μ„œλΆ€ν„° bfs둜 νƒμƒ‰ν–ˆλŠ”λ° νŒŒμ΄μ¬μ€ μ‹œκ°„μ΄ˆκ³Όκ°€ λ‚˜λ„€μš”γ…œ 1μ‹œκ°„λ™μ•ˆ 머리 μ‹Έλ§€λ‹€κ°€ κ·Έλƒ₯ μžλ°”λ‘œ κ°ˆμ•„νƒ”μŠ΅λ‹ˆλ‹€ :)

같은 λ‘œμ§μ„ μžλ°”λ‘œ κ΅¬ν˜„ν–ˆμ„λ• 30λΆ„λ§Œμ— ν’€ 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. μ—­μ‹œ μ΅μˆ™ν•œκ²Œ μ΅œκ³ λ„€μš”

import java.util.*;

class Solution {
    char[][] container;
    int n, m;
    int[][] offset = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        
    public int solution(String[] storage, String[] requests) {
        n = storage.length;
        m = storage[0].length();
        int answer = n * m;
        
        container = padding(storage);
        
        for (String req : requests) {
            if (req.length() == 1){
                answer -= one(req.charAt(0));
            } else {
                answer -= two(req.charAt(0));
            }
        }
        return answer;
    }
    
    private char[][] padding(String[] storage) {
        char[][] ret = new char[n+2][m+2];
        Arrays.fill(ret[0], ' ');
        Arrays.fill(ret[n+1], ' ');
        for (int i = 0; i < n; i++) {
            ret[i+1][0] = ' ';
            ret[i+1][m+1] = ' ';
            for (int j = 0; j < m; j++) {
                ret[i+1][j+1] = storage[i].charAt(j);
            }
        }
        return ret;
    }
    
    private int one(char target) {
        int count = 0;
        Queue<int[]> q = new ArrayDeque<>();
        boolean[][] visited = new boolean[n+2][m+2];
        q.add(new int[]{0, 0});
        visited[0][0] = true;
        
        while (!q.isEmpty()) {
            int x = q.peek()[0];
            int y = q.poll()[1];
            
            for (int[] o : offset) {
                int nx = x + o[0];
                int ny = y + o[1];
                if (nx < 0 || nx >= m+2 || ny < 0 || ny >= n + 2) continue;
                if (visited[ny][nx]) continue;
                if (container[ny][nx] == target) {
                    visited[ny][nx] = true;
                    container[ny][nx] = ' ';
                    count++;
                }
                else if (container[ny][nx] == ' ') {
                    visited[ny][nx] = true;
                    q.offer(new int[]{nx, ny});
                }
            }
        }
        //System.out.println("one: "+count);
        return count;
    }
    
    private int two(char target) {
        int count = 0;
        for (int i = 0; i < n+2; i++) {
            for (int j = 0; j < m+2; j++) {
                if (container[i][j] == target) {
                    container[i][j] = ' ';
                    count++;
                }
            }
        }
        //System.out.println("two: "+count);
        return count;
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants