파이썬 알고리즘 019 | 봉우리

Yunny.Log ·2021년 1월 8일
0

Algorithm

목록 보기
19/318
post-thumbnail

19. 봉우리

지도 정보가 N*N 격자판에 주어집니다. 각 격자에는 그 지역의 높이가 쓰여있습니다. 각 격자
판의 숫자 중 자신의 상하좌우 숫자보다 큰 숫자는 봉우리 지역입니다. 봉우리 지역이 몇 개
있는 지 알아내는 프로그램을 작성하세요.
격자의 가장자리는 0으로 초기화 되었다고 가정한다.
만약 N=5 이고, 격자판의 숫자가 다음과 같다면 봉우리의 개수는 10개입니다.

0 0 0 0 0 0 0
0 5 3 7 2 3 0
0 3 7 1 6 1 0
0 7 2 5 3 4 0
0 4 3 6 4 1 0
0 8 7 3 5 2 0
0 0 0 0 0 0 0

▣ 입력설명
첫 줄에 자연수 N이 주어진다.(1<=N<=50)
두 번째 줄부터 N줄에 걸쳐 각 줄에 N개의 자연수가 주어진다. 각 자연수는 100을 넘지 않는
다.

▣ 출력설명
봉우리의 개수를 출력하세요.

▣ 입력예제 1
5
5 3 7 2 3
3 7 1 6 1
7 2 5 3 4
4 3 6 4 1
8 7 3 5 2

▣ 출력예제 1
10

<내 풀이>

n=int(input())
a=[list(map(int,input().split())) for _ in range(n)]
#0으로 감싸주기
for i in range(n):
    a[i].append(0)
    a[i].insert(0,0)
a.append([0]*(n+2))
a.insert(0, [0]*(n+2))

cnt=0
for i in range(1,n+1): #가장자리애들은 놔두어야 하니깐
    for j in range(1,n+1):
        if a[i][j] > a[i][j-1] and a[i][j]>a[i][j+1] and a[i][j]>a[i-1][j] and a[i][j]>a[i+1][j]:
            cnt+=1
print(cnt)

근데 과연 0으로 둘러주는 행위가 맞는지 궁금 => 맞았다
그리고 코드가 너무 길고 더러운 것 같다 => 이것도 맞다..

<풀이>

pdx=[-1, 0, 1, 0]
dy=[0, 1, 0, -1]  #행렬 상하좌우 비교용
n=int(input())
a=[list(map(int, input().split())) for _ in range(n)]
a.insert(0, [0]*n) #0으로 초기화해주는 것 a[0]
a.append([0]*n)		#0으로 초기화 a[n]
for x in a:
    x.insert(0, 0)
    x.append(0)

cnt=0
for i in range(1, n+1):
    for j in range(1, n+1):
        if all(a[i][j]>a[i+dx[k]][j+dy[k]] for k in range(4)):
            cnt+=1
print(cnt)

<반성점>

  • 너무 조잡한 비교였다
if a[i][j] > a[i][j-1] and a[i][j]>a[i][j+1] and a[i][j]>a[i-1][j] and a[i][j]>a[i+1][j]:

=>나는 이렇게 했는데 all사용하면 깔끔

if all(a[i][j]>a[i+dx[k]][j+dy[k]] for k in range(4)):

<배운 점>

  • 행렬 가장자리 0으로 초기화 하는 법: 첫 행과 끝 행에 [0]으로 초기화 한 행렬을 insert/append 하고, 새 행렬 양 끝에 insert/append로 0 추가한다.

  • a안에 있는 리스트들의 a[0]과 a[n-1]에 0 덧붙여줄 때


a.append([0]*(n+2))
a.insert(0, [0]*(n+2))

=> 나는 이렇게 했는데

for x in a: #이렇게 나오면 리스트들 순차대로 나오니깐
    x.insert(0, 0) #그 리스트의 앞에 0 붙이기
    x.append(0)		# 그 리스트의 뒤에 0 붙이기

=> 반복문을 이용해서 할 수도 있다

  • 행렬에서 상하좌우 탐색하는 법: x,y좌표를 이동시켜주는 리스트인 dx[-1,0,1,0] dy[0,1,0,-1]를 만들고, [i+dx[k]][j+dy[k]]를 k 기준으로 4번 반복하면 상하좌우 탐색이 가능하다.

  • all(): 인자의 내용이 모두 참이어야 True 리턴. 하나라도 False일 시 False 리턴. 모두 참이어야 하는 경우를 찾을 때 하나하나 쓸 필요 없어서 유용

  • all
    : 모든 것이 참일때만 참이다, 하나라도 거짓이면 거짓

if all(50 > x for x in a) : 
	print('yes')
else : 
	print('no')

=> 하나라도 참이 아니면 거짓

0개의 댓글