import sys def find_parents(X): if X == make_set[X]: return X make_set[X] = find_parents(make_set[X]) return make_set[X] def union(x,y): X = find_parents(x) Y = find_parents(y) if X !=Y: if ranks[X]< ranks[Y]: X,Y = Y,X make_set[Y] = X if ranks[X] == ranks[Y]: ranks[X] += 1 return True return False def input(): return sys.stdin.readline().rstrip() N,M = map(int,input().split()) dire = { "U": [-1,0], "L": [0,-1], "R" : [0, 1], 'D': [1,0] } arr = [list(input()) for _ in range(N)] make_set = [i for i in range(N*M)] ranks = [1 for _ in range(N*M)] for x in range(N): for y in range(M): point = x*M+y dx,dy = dire[arr[x][y]] next_point = (x+dx)*M+y+dy union(point,next_point) result = 0 for x in range(N): for y in range(M): point = x*M+y if point == find_parents(point): result += 1 print(result)
이 문제는 union find를 통해 집합이 몇개가 되는지 확인하면 된다.
그 방법은 현재 노드와 부모노드가 동일한 개수를 세주면 된다.
import sys def input(): return sys.stdin.readline().rstrip() N,M = map(int,input().split()) dire = { "U": [-1,0], "L": [0,-1], "R" : [0, 1], 'D': [1,0] } arr = [list(input()) for _ in range(N)] visited = [[-1 for _ in range(M)] for _ in range(N)] result = 0 for x in range(N): for y in range(M): if visited[x][y] != -1: continue point = x*M+y nx,ny = x,y while visited[nx][ny] == -1: visited[nx][ny] = point dx,dy = dire[arr[nx][ny]] nx = nx + dx ny = ny + dy if visited[nx][ny] == point: result += 1 print(result)
다르게 푸는 방식은 visited를 만들어놓고 같은 point가 되는 지점에 돌아왔을때 result + 1 해주는 것이다.
안전지대가 된다는 것은 한 지점에서 출발했다가 원래지점으로 돌아온다는것을 뜻하므로, 그 조건을 만족하는 개수를 세주면 된다.
'알고리즘 > 백준' 카테고리의 다른 글
[BOJ/백준] 2211 네트워크 복구 (0) | 2021.07.31 |
---|---|
[BOJ/백준] 1944 복제 로봇 (0) | 2021.07.31 |
[BOJ/백준] 17951 흩날리는 시험지 속에서 내 평점이 느껴진거야 (0) | 2021.07.12 |
[BOJ/백준] 16571 알파 틱택토 (0) | 2021.07.12 |
[BOJ/백준] 16437 양 구출 작전 (0) | 2021.07.12 |