Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

37-Munbin-Lee #150

Merged
merged 1 commit into from
Mar 7, 2024
Merged

37-Munbin-Lee #150

merged 1 commit into from
Mar 7, 2024

Conversation

Munbin-Lee
Copy link
Member

@Munbin-Lee Munbin-Lee commented Mar 5, 2024

πŸ”— 문제 링크

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

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

1μ‹œκ°„

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

문제 μ„€λͺ…

μ—΄ ν•˜λ‚˜λ₯Ό κ΄€ν†΅ν•˜λ„λ‘ μ‹œμΆ”κ΄€μ„ κ½‚λŠ”λ‹€.

μ‹œμΆ”κ΄€μ€ ν•΄λ‹Ή 열에 ν¬ν•¨λœ λͺ¨λ“  μ„μœ  λ©μ–΄λ¦¬μ˜ μ„μœ λ₯Ό λ½‘λŠ”λ‹€.

μž„μ˜μ˜ 열에 μ‹œμΆ”κ΄€μ„ κ½‚μ•˜μ„ λ•Œ, 뽑을 수 μžˆλŠ” μ΅œλŒ€μ˜ μ„μœ λŸ‰μ€?


νš¨μœ¨μ„± ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ μ œν•œμ‚¬ν•­

주어진 쑰건 μ™Έ μΆ”κ°€ μ œν•œμ‚¬ν•­ μ—†μŠ΅λ‹ˆλ‹€.

백쀀도 가끔 μ œν•œμ‚¬ν•­μ΄ 무엇인지 μ•Œλ €μ£Όμ§€ μ•ŠλŠ”λ°, κ°œμΈμ μœΌλ‘œλŠ” 쑰금 λΆˆνŽΈν•˜λ‹€.

정말 μ œν•œμ‚¬ν•­μ΄ μ—†λ‹€λ©΄ μž…λ ₯이 1μ–΅ 개 λ„˜κ²Œ λ“€μ–΄μ˜¬ μˆ˜λ„ μžˆλ‹€λŠ” 건데, μ‹€μ œλ‘œ 그럴 λ¦¬λŠ” μ—†μœΌλ‹ˆκΉŒ...

μ–΄μ¨Œλ“  이 μ œν•œμ‚¬ν•­μ„ 보고 μ΅œλŒ€ν•œ 효율적으둜 κ΅¬ν˜„ν•΄μ•Όκ² λ‹€κ³  μƒκ°ν–ˆλ‹€.


λ¨Όμ €, μ„μœ  덩어리λ₯Ό μ–΄λ–»κ²Œ 체크할 지 μƒκ°ν–ˆλ‹€.

BFS, DFS, μœ λ‹ˆμ˜¨νŒŒμΈλ“œ 정도가 μƒκ°λ‚¬λŠ”λ°,

μ–΄μ°¨ν”Ό 각 셀은 ν•œ λ²ˆμ”©λ§Œ λ°©λ¬Έν•˜λ―€λ‘œ O(land의 넓이) 라 무슨 방법을 μ„ νƒν•˜λ“  효율적인데

ꡳ이 μœ λ‹ˆμ˜¨νŒŒμΈλ“œλ‘œ λŒμ•„κ°ˆ ν•„μš”λŠ” μ—†λ‹€κ³  μƒκ°ν–ˆκ³ ,

μž¬κ·€λ₯Ό μ•ˆ μ“°κ³  κ΅¬ν˜„ν•˜λŠ” 게 깔끔할 것 κ°™μ•„ BFS둜 μ²΄ν¬ν•˜κΈ°λ‘œ ν–ˆλ‹€.


각 μ‹œμΆ”κ΄€μ„ 꽂을 λ•Œλ§ˆλ‹€ BFS둜 μ²΄ν¬ν•œλ‹€λ©΄, 이미 ν–ˆλ˜ 연산을 λ‹€μ‹œ ν•˜κΈ° λ•Œλ¬Έμ— λΉ„νš¨μœ¨μ μ΄λ‹€.

κ·Έλž˜μ„œ μ „μ²˜λ¦¬λ‘œ BFSλ₯Ό ν•œλ²ˆλ§Œ ν•˜κΈ°λ‘œ ν–ˆλ‹€.

λŒ€λž΅μ μΈ 방법은 λ‹€μŒκ³Ό κ°™λ‹€.

image

각 μ˜€μΌμ— λŒ€ν•˜μ—¬ μ–΄λ–€ 청크(덩어리)인지 번호λ₯Ό 맀기고,

각 청크의 μ˜€μΌλŸ‰μ΄ μ–Όλ§ˆμΈμ§€ μ €μž₯ν•˜λŠ” 것이닀.

이제 μ½”λ“œλ‘œ κ΅¬ν˜„ν•΄λ³΄μž.


vector<vector<int>> chunks(r, vector<int> (c, -1));
vector<int> oils;

chunksλŠ” 각 셀이 λͺ‡ 번 청크인지λ₯Ό μ €μž₯ν•œλ‹€. μ„μœ κ°€ μ•„λ‹ˆλΌλ©΄ -1이닀.

oilsλŠ” 각 청크의 μ„μœ λŸ‰μ„ μ €μž₯ν•œλ‹€.


auto bfs = [&](int y, int x, int chunk) {
	// ν•΄λ‹Ή μ…€μ˜ 청크와, κ·Έ 청크의 μ„μœ λŸ‰μ„ μ €μž₯ν•œλ‹€.
};

for (int y = 0; y < r; y++) {
	for (int x = 0; x < c; x++) {
		// λ°©λ¬Έ μ²˜λ¦¬λŠ” μ…€μ˜ land 값을 0으둜 λ§Œλ“œλŠ” λ°©μ‹μœΌλ‘œ ν•œλ‹€.
		if (land[y][x] == 0) continue;
		
		land[y][x] = 0;
		bfs(y, x, oils.size());
	}
} 

λͺ¨λ“  셀에 λŒ€ν•΄ BFSλ₯Ό 돌렀 chunks와 oilsλ₯Ό μ™„μ„±ν•œλ‹€.


int answer = -1;

// λͺ¨λ“  열에 λŒ€ν•΄ μ‹œμΆ”κ΄€μ„ 꽂은 ν›„ μ΅œλŒ€ μ„μœ λŸ‰μ„ κ΅¬ν•œλ‹€.
for (int x = 0; x < c; x++) {

	// μ²­ν¬λŠ” 쀑볡될 μˆ˜λ„ 있기 λ•Œλ¬Έμ— set을 μ‚¬μš©ν•œλ‹€.
	unordered_set<int> set;
	
	for (int y = 0; y < r; y++) {
		int chunk = chunks[y][x];
		
		if (chunk == -1) continue;
		
		set.emplace(chunk);
	}
	
	// μ‹œμΆ”κ΄€μ΄ κ΄€ν†΅ν•œ λͺ¨λ“  청크의 μ„μœ λŸ‰μ„ λ”ν•œλ‹€.
	int oil = 0;
	
	for (int chunk : set) {
		oil += oils[chunk];
	}
	
	answer = max(answer, oil);
}

return answer;

νŠΉλ³„ν•œ μ•Œκ³ λ¦¬μ¦˜μ΄λ‚˜ 아이디어λ₯Ό 쓰지 μ•Šκ³  ν’€ 수 있게 λ§Œλ“  μž¬λ°ŒλŠ” 문제인 것 κ°™λ‹€.

지문도 ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€λ‹΅μ§€ μ•Šκ²Œ ꡉμž₯히 κΉ”λ”ν•œλ° PCCP λ¬Έμ œλΌμ„œ κ·ΈλŸ°κ°€...

λ‹€μŒμ—λ„ PCCP 문제λ₯Ό ν’€μ–΄μ„œ 비ꡐ해봐야겠닀.

πŸ“š 전체 μ½”λ“œ

#include <iostream>
#include <vector>
#include <queue>
#include <unordered_set>

using namespace std;

int solution(vector<vector<int>> land) {
    int r = land.size();
    int c = land[0].size();
    
    int dy[4] {-1, 0, 1, 0};
    int dx[4] {0, -1, 0, 1};
    
    vector<vector<int>> chunks(r, vector<int> (c, -1));
    vector<int> oils;
    
    auto bfs = [&](int y, int x, int chunk) {
        queue<pair<int, int>> q;
        q.emplace(y, x);
        
        int oil = 0;
        
        while (!q.empty()) {
            auto [cy, cx] = q.front();
            q.pop();

            oil++;
            chunks[cy][cx] = chunk;

            for (int dir = 0; dir < 4; dir++) {
                int ny = cy + dy[dir];
                int nx = cx + dx[dir];

                if (ny == -1 || ny == r || nx == -1 || nx == c) continue;
                if (land[ny][nx] == 0) continue;

                land[ny][nx] = 0;
                q.emplace(ny, nx);
            }
        }
        
        oils.emplace_back(oil);
    };
    
    for (int y = 0; y < r; y++) {
        for (int x = 0; x < c; x++) {
            if (land[y][x] == 0) continue;
            
            land[y][x] = 0;
            bfs(y, x, oils.size());
        }
    }
    
    int answer = -1;
    
    for (int x = 0; x < c; x++) {
        unordered_set<int> set;
        
        for (int y = 0; y < r; y++) {
            int chunk = chunks[y][x];
            
            if (chunk == -1) continue;
            
            set.emplace(chunk);
        }
        
        int oil = 0;
        
        for (int chunk : set) {
            oil += oils[chunk];
        }
        
        answer = max(answer, oil);
    }
    
    return answer;
}

Copy link
Member

@tgyuuAn tgyuuAn left a comment

Choose a reason for hiding this comment

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

νš¨μœ¨μ„± ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ μ œν•œμ‚¬ν•­

주어진 쑰건 μ™Έ μΆ”κ°€ μ œν•œμ‚¬ν•­ μ—†μŠ΅λ‹ˆλ‹€.

백쀀도 가끔 μ œν•œμ‚¬ν•­μ΄ 무엇인지 μ•Œλ €μ£Όμ§€ μ•ŠλŠ”λ°, κ°œμΈμ μœΌλ‘œλŠ” 쑰금 λΆˆνŽΈν•˜λ‹€.

정말 μ œν•œμ‚¬ν•­μ΄ μ—†λ‹€λ©΄ μž…λ ₯이 1μ–΅ 개 λ„˜κ²Œ λ“€μ–΄μ˜¬ μˆ˜λ„ μžˆλ‹€λŠ” 건데, μ‹€μ œλ‘œ 그럴 λ¦¬λŠ” μ—†μœΌλ‹ˆκΉŒ...

μ–΄μ¨Œλ“  이 μ œν•œμ‚¬ν•­μ„ 보고 μ΅œλŒ€ν•œ 효율적으둜 κ΅¬ν˜„ν•΄μ•Όκ² λ‹€κ³  μƒκ°ν–ˆλ‹€.




νš¨μœ¨μ„± ν…ŒμŠ€νŠΈμ— μ΅œλŒ€ n = 500이라고 λ˜μ–΄ μžˆλ„€μš” !!!!!




저도 λ¬ΈλΉˆλ‹˜μ΄λž‘ λ˜‘κ°™μ΄ BFS, DFS, μœ λ‹ˆμ˜¨ νŒŒμΈλ“œ μƒκ°ν–ˆμ–΄μš”.

근데 μœ λ‹ˆμ˜¨ νŒŒμΈλ“œλŠ” λ„ˆλ¬΄ λŒμ•„κ°€λŠ” 거라고 μƒκ°ν–ˆκ³ , DFS BFSλ‘œλ„ κ°„λ‹¨νžˆ 풀리겠닀 μƒκ°ν•΄μ„œ DFS둜 ν•΄κ²° ν–ˆμ”λ‹ˆλ‹€,

문제 μž¬λ°Œλ„€μš” ν—ˆν—ˆ

from collections import defaultdict
import sys

sys.setrecursionlimit(1000000)

temp = 0
def dfs(y, x, visited, land, col_info):
    global temp

    n_y = len(land)
    n_x = len(land[0])

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

    for dir in range(4):
        new_y = y+dy[dir]
        new_x = x+dx[dir]

        if new_y < 0 or new_y >= n_y: continue
        if new_x < 0 or new_x >= n_x: continue
        if (new_y, new_x) in visited: continue
        if land[new_y][new_x] == 0: continue

        visited.add((new_y, new_x))
        col_info.add(new_x)
        temp += 1
        dfs(new_y, new_x, visited, land, col_info)

def solution(land):
    global temp

    visited = set()
    
    n_row = len(land)
    n_col = len(land[0])
    oil_info = defaultdict(int)

    for row in range(n_row):
        for col in range(n_col):
            if land[row][col] == 1 and (row, col) not in visited:
                temp = 1
                col_info = {col,}
                visited.add((row,col))
                dfs(row, col, visited, land, col_info)

                for c in col_info:
                    oil_info[c] += temp
                    
    return max(list(oil_info.values()))

land = [[0, 0, 0, 1, 1, 1, 0, 0], [0, 0, 0, 0, 1, 1, 0, 0], [1, 1, 0, 0, 0, 1, 1, 0], [1, 1, 1, 0, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0, 1, 1]]
print(solution(land))

@pknujsp
Copy link
Collaborator

pknujsp commented Mar 5, 2024

μˆ˜κ³ ν•˜μ…¨μŠ΅λ‹ˆλ‹€ 문제 κΉ”λ”ν•˜κ³  μ’‹λ„€μš”

저도 BFSλ₯Ό 기본으둜 ν•΄μ„œ ν’€μ—ˆμ–΄μš”

  • landλ₯Ό 첫번째 ν–‰, μ—΄μ—μ„œ μ‹œμž‘ν•΄μ„œ 였λ₯Έμͺ½ λ°©ν–₯으둜 ν•œ ν–‰μ”© ν›‘μœΌλ©΄μ„œ λ‹€μŒ μž‘μ—…μ„ ν•©λ‹ˆλ‹€
  • ν›‘κ³  μžˆλŠ” ν–‰κ³Ό μ—΄μ˜ 값이 1 이면 μ—¬κΈ°μ—μ„œ BFSλ₯Ό ν•΄μ„œ 총 μ‹œμΆ”λŸ‰μ„ κ΅¬ν•˜κ³ 
  • BFS 쀑에 λ“€λ¦° 열을 set에 λͺ¨λ‘ λ‹΄μ•„μ„œ μ—΄ λ³„λ‘œ 총 μ‹œμΆ”λŸ‰μ„ κΈ°λ‘ν•©λ‹ˆλ‹€
  • ν™•μΈν•œ 지점은 값을 0으둜 λ°”κΏ”μ„œ λ‚˜μ€‘μ— λ‹€μ‹œ νƒμƒ‰ν•˜μ§€ μ•Šκ²Œ ν•΄μ€λ‹ˆλ‹€
  • λͺ¨λ“  지점을 λ‹€ 훑은 ν›„μ—λŠ” ν™•μΈν•œ μ—΄ μ€‘μ—μ„œ μ‹œμΆ”λŸ‰μ΄ μ΅œλŒ€κ°’μΈ 것을 λ°˜ν™˜ν•©λ‹ˆλ‹€
from collections import *

def solution(land):
    answer = 0
    cols = [0] * len(land[0])
    dr = [1,-1,0,0]
    dc = [0,0,-1,1]
    
    for row in range(len(land)):
        for col in range(len(land[0])):
            if land[row][col] == 0:
                continue
                
            q = deque([(row, col)])        
            check_cols = set()
            t = 0
            land[row][col] = 0
            
            while q:
                r, c = q.popleft()
                check_cols.add(c)
                t += 1
                
                for i in range(4):
                    nr = r + dr[i]
                    nc = c + dc[i]
                    if not 0 <= nr < len(land) or not 0 <= nc < len(land[0]):
                        continue
                    if land[nr][nc] == 0:
                        continue
                        
                    land[nr][nc] = 0
                    q.append((nr, nc))
                    
            for c in check_cols:
                cols[c] += t
                
    return max(cols)

Copy link
Collaborator

@H0ngJu H0ngJu left a comment

Choose a reason for hiding this comment

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

였였 이거 μ €λ²ˆν•™κΈ° 자료ꡬ쑰 λ•Œ λ°°μ› λ˜ λ―Έλ‘œνƒˆμΆœ λ¬Έμ œλž‘ λΉ„μŠ·ν•˜λ„€μš”
κ°€λŠ₯ν•œ 경둜λ₯Ό λͺ¨λ‘ νƒμƒ‰ν•˜λŠ” κ±°μ˜€λŠ”λ°, κ·Έ λ•Œλ„ bfs둜 κ΅¬ν˜„ν–ˆλ„€μš”

κ·Έλž˜μ„œ bfs, dfsλŠ” λ– μ˜¬λ¦΄ 수 μžˆμ—ˆλŠ”λ° μœ λ‹ˆμ˜¨ νŒŒμΈλ“œλŠ” 처음 λ“€μ–΄λ³΄λŠ” κ°œλ…μ΄λ„€μš” ..γ…Žγ…Ž
덕뢄에 ν•˜λ‚˜ 또 λ°°μ›Œκ°‘λ‹ˆλ‹€. μˆ˜κ³ ν•˜μ…¨μŠ΄λ‹€ -!

@Munbin-Lee Munbin-Lee merged commit 7e66693 into main Mar 7, 2024
1 check passed
@Munbin-Lee Munbin-Lee deleted the 37-Munbin-Lee branch March 7, 2024 03:36
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.

5 participants