(처음 든 생각)
일단 맵을 만들자.
그리고 나서 생각을 다시 해보자,
빗물이 차오르게 하려면?
양 옆에 빗물을 가둘 수 있는 기둥이 존재해야 한다.
위 그림에서는 양 옆에 빗물을 가둘 수 있게끔 기둥이 존재하고,
왼쪽 기둥은 높이가 3, 오른쪽 기둥높이는 4이다.
이때는 왼쪽 기둥의 높이에 맞춰야한다. (즉 최솟값)
그래서 이때 든 생각은
바닥부터 탐색을 시작해서
체크를 하자..?
여기서도 마찬가지로 왼쪽 빗물부터 보면,
왼쪽 기둥 높이는 3, 오른쪽 기둥 높이는 4
이때도 3을 선택
오른쪽 빗물은 왼쪾 기둥이 4, 오른쪽 기둥 높이가 2
따라서 2를 선택
위 그림에서는 빗물이 고일 수가 없다.
기둥이 1개만 존재하기 때문이다.
(내가 맨 처음에 성공했던 풀이)
맨 아래부터 탐색을 시작한다.
h, w = map(int, input().split()) # 행,열
array = [[0 for _ in range(w)] for i in range(h)]
b_h = list(map(int, input().split()))
for i in range(w):
if b_h[i] == 0:
continue
for j in range(b_h[i]):
array[h - 1 - j][i] = 1
2차원 배열로 블록이 채워져있는 공간은 1, 비어있는 칸은 0으로 맵 초기화
# 탐색 시작
answer = 0 # 최종값
for i in range(h - 1, -1, -1): #h-1행부터 0행까지 탐색
start = 0 # start 블록
end = 0 # end 블록
num = 0 # 중간중간 빗물 담는 변수
for j in range(w): # 0행부터 w-1행까지 탐색
if start == 0:
if array[i][j] == 1:
start = 1
continue
else:
if end == 0:
if array[i][j] == 0:
if j == w - 1:
continue
num += 1
continue
else:
end = 1
answer += num
num = 0
continue
else:
if array[i][j] == 1:
continue
else:
end = 0
num += 1
if start == 1 and end == 0:
num = 0
else:
answer += num
print(answer)
■□□□■를 예시로 들어보면,
맨 앞에 있는 ■가 start
맨 뒤에 있는 ■가 end
만약 빗물 앞에 오는 ■가 없는 상황에 현재 위치에 ■가 있을 경우
-> start=1
start=1, 즉 앞에 ■가 있는 경우
만약 뒤에 와야 하는 ■가 없을 경우
계속 빗물을 넣는다. ■가 나올때까지
끝까지 다 왔는데 ■가 없다면? 방금 셋던 값은 answer에 넣지 않는다.
만약 현재 위치에 ■가 있을 경우 (end)
-> end=1
answer에 좀전까지 세고 있었던 빗물수를 넣고,
num값은 다시 초기화해준다.
만약 end=1인 경우,
현재 위치에 ■가 있으면 continue
: ■□■(■■)□□■ , 괄호친 부분임
■가 없으면, end=0으로 초기화, num+=1
: ■□■(□)□■. 괄호친 부분임
해당 행의 탐색을 마친 후,
만약 start값은 1인데, end가 0인 경우
방금 계산했던 num값이 쓰레기라는 뜻.
예를 들면, ■□□□□□였는데 □의 개수가 num에 있다는 뜻!
그러니 5개는 answer값에 포함되면 안된다.
start==1이고 end==0이 아니면,
answer+=num
전체코드
# 2차원 배열로 블록이 채워져있는 공간은 1, 비어있는 칸은 0으로 맵 초기화
h, w = map(int, input().split()) # 행,열
array = [[0 for _ in range(w)] for i in range(h)]
b_h = list(map(int, input().split()))
for i in range(w):
if b_h[i] == 0:
continue
for j in range(b_h[i]):
array[h - 1 - j][i] = 1
# 탐색 시작
answer = 0 # 최종값
for i in range(h - 1, -1, -1): #h-1행부터 0행까지 탐색
start = 0 # start 블록
end = 0 # end 블록
num = 0 # 중간중간 빗물 담는 변수
for j in range(w): # 0행부터 w-1행까지 탐색
if start == 0:
if array[i][j] == 1:
start = 1
continue
else:
if end == 0:
if array[i][j] == 0:
if j == w - 1:
continue
num += 1
continue
else:
end = 1
answer += num
num = 0
continue
else:
if array[i][j] == 1:
continue
else:
end = 0
num += 1
if start == 1 and end == 0:
num = 0
else:
answer += num
print(answer)
(인터넷에서 찾아본 풀이 참고)
현재 위치를 기준으로 왼쪽과 오른쪽에서 가장 큰 값을 각각 left,right 변수에 저장
left와 right 중 가장 작은 값이 만약 현재 위치의 블록개수보다 작다면?
-> cnt+=min(left,right)-array[i] : 최종 빗물개수
min(left,right) = 3
현재 위치 값 array[i]=1
cnt+=3-1=2
array[i]>min(left,right)
-> 빗물이 들어갈 공간이 없으므로 continue
h, w = map(int, input().split()) # 세로,가로
array = list(map(int, input().split()))
cnt = 0
for i in range(0, len(array)):
left = max(array[:i + 1])
right = max(array[i:])
if array[i]>min(left,right):
continue
else:
cnt+=min(left,right)-array[i]
print(cnt)
'여니의 취준 준비 > 코딩테스트 (Python)' 카테고리의 다른 글
[n3273] 두수의 합 in python (0) | 2021.08.28 |
---|---|
[프로그래머스] 거리두기 확인하기 in python (0) | 2021.08.27 |
[n16928] 뱀과 사다리 게임 (0) | 2021.08.26 |
[n12919] A와 B 2 in python (0) | 2021.08.25 |
[n13699] 점화식 (0) | 2021.08.24 |