백준_1012_유기농 배추

임정민·2023년 6월 11일
1

알고리즘 문제풀이

목록 보기
61/173
post-thumbnail

백준 너비 우선 탐색 문제풀이 입니다.

문제

https://www.acmicpc.net/problem/1012

[나의 풀이1]

T = int(input())

farms = []
visited = []

for i in range(T):
    M, N, K = map(int, input().split())

    farms.append([[0] * N for x in range(M)])
    visited.append([[False] * N for x in range(M)])

    for j in range(K):
        x, y = map(int, input().split())

        farms[i][x][y] = 1

from collections import deque

# 상우하좌
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]

for t in range(len(farms)):
    length = len(farms[t])
    width = len(farms[t][0])

    print("가로 : ", length,"세로 : ",width)

    ans = 0
    add = 0
    queue = deque([[0, 0]])
    visited[t][0][0] = True
    last_v = [0,0]
    ans_list = []

    if farms[t][0][0] == 1:
        ans_list.append([0,0])

    while queue:

        print("queue : ",queue) 
        v = queue.popleft()
        print("현재 좌표 : ", v[0], v[1])
        
        for i in range(4):
            if v[0] + dx[i] >= 0 and v[0] + dx[i] < length and v[1] + dy[i] >= 0 and v[1] + dy[i] < width :
                if not visited[t][v[0] + dx[i]][v[1] + dy[i]]:
                    if farms[t][v[0] + dx[i]][v[1] + dy[i]] == 1:
                        queue.appendleft([v[0] + dx[i], v[1] + dy[i]])
                        ans_list.append([v[0] + dx[i], v[1] + dy[i]])
                    else:
                        queue.append([v[0] + dx[i], v[1] + dy[i]])
                    visited[t][v[0] + dx[i]][v[1] + dy[i]] = True

        last_v = v

    last_x0 = ans_list[0][0]
    last_x1 = ans_list[0][1]

    if len(ans_list) == 1:
        ans = 1
        print(ans)
        break

    ans_list = sorted(ans_list)

    for idx,x in enumerate(ans_list):

        if idx == len(ans_list)-1:
            break
        if (abs(ans_list[idx][0] - ans_list[idx+1][0]) == 1 and ans_list[idx][1] - ans_list[idx+1][1] == 0) or (ans_list[idx][0] - ans_list[idx+1][0] == 0 and abs(ans_list[idx][1] - ans_list[idx+1][1]) == 1) :
            continue
        print()
        print("ans 추가 : ", idx,x)
        ans += 1

    print(ans_list)
    print(ans)

너비 우선 탐색 작동 방식은 이해하고 있지만 풀이 접근을 잘못하여 해결하지 못하였습니다. 위 코드는 너비 우선 탐색 방식으로 1(양배추)인 좌표를 우선으로 조사하여 ans_list(양배추 좌표)를 appendleft하고 0(비어있는) 좌표를 오른쪽에 append한 뒤 ans_list를 순차적으로 돌며 좌표차이가 ±1인 좌표를 묶어 양배추 더미의 갯수를 조사하려고 했습니다. 하지만 이러한 방식은 예를 들어

ans_list = [[0, 0], [1, 0], [1, 1], [2, 4], [3, 4], [4, 2], [4, 3], [4, 5], [7, 4], [7, 5], [7, 6], [8, 4], [8, 5], [8, 6], [9, 4], [9, 5], [9, 6]]

일 때, [7,6] 과 [8,6]은 같은 더미임에도 불구하고 [0, 0], [1, 0], [1, 1] / [2, 4], [3, 4] / [4, 2], [4, 3] / [4, 5] / [7, 4], [7, 5], [7, 6] / [8, 4], [8, 5], [8, 6] ... 씩 끊어 세기 때문에 정답보다 더 많은 더미로 출력되었습니다. 해결하기 어려워 다른 풀이를 참고하였습니다.🧸🧸🧸

[나의 풀이2]

T = int(input())

def bfs(farm,x,y):

    from collections import deque

    queue = deque([[x,y]])
    visited[x][y] = True
    
    while queue:

        v = queue.popleft()
        
        x = v[0]
        y = v[1]

        farm[x][y] = 0
            
        for k in range(4):
            Newx = x + dx[k]
            Newy = y + dy[k]

            if Newx >=0 and Newx < M and Newy >= 0 and Newy < N:
                if not visited[Newx][Newy]:
                    if farm[Newx][Newy] == 1:
                        queue.append([Newx,Newy])
                        visited[Newx][Newy] = True

        # print(queue)

# 상우하좌
dx = [-1,0,1,0]
dy = [0,1,0,-1]      

for _ in range(T):
    M, N, K = map(int,input().split())

    farm = [[0]*N for m in range(M)]
    visited = [[False]*N for m in range(M)]

    for k in range(K):

        i,j = map(int,input().split())
        farm[i][j] = 1

    ans = 0
    for x in range(M):
        for y in range(N):

            if farm[x][y] == 1:
                ans += 1
                bfs(farm,x,y)
    
    print(ans)

[다른사람의 풀이]

from collections import deque

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

t = int(input())

def bfs(graph, a, b):
    queue = deque()
    queue.append((a,b))
    graph[a][b] = 0

    while queue:
        x, y = queue.popleft()
        for i in range(4):
            nx = x+dx[i]
            ny = y+dy[i]
            if nx < 0 or nx >=n or ny < 0 or ny >= m:
                continue
            if graph[nx][ny] == 1:
                graph[nx][ny] = 0
                queue.append((nx, ny))
    return

for i in range(t):
    cnt = 0
    n, m, k = map(int,input().split())
    graph = [[0]*m for _ in range(n)]

    for j in range(k):
        x, y = map(int, input().split())
        graph[x][y] = 1

    for a in range(n):
        for b in range(m):
            if graph[a][b] == 1:
                bfs(graph, a, b)
                cnt += 1
    print(cnt)

위 다른 사람의 풀이와 같이 전체 농장을 돌며 여러 양배추 더미 중 한 부분을 탐지하면 이와 연결된 1을 모두 파악하여 0으로 바꾸며 한 더미씩 세는 방식이었습니다. 양배추인 좌표(값이 1인 좌표)를 우선으로 탐색하기 위해 bfs 구조를 사용한 것을 깨달을 수 있었습니다.🦝🦝🦝

감사합니다.

profile
https://github.com/min731

0개의 댓글