문제풀이/구현

[파이썬] [구현] 백준 14890 경사로

승무_ 2023. 4. 7. 17:02

문제

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

 

14890번: 경사로

첫째 줄에 N (2 ≤ N ≤ 100)과 L (1 ≤ L ≤ N)이 주어진다. 둘째 줄부터 N개의 줄에 지도가 주어진다. 각 칸의 높이는 10보다 작거나 같은 자연수이다.

www.acmicpc.net

코드

import sys
input=sys.stdin.readline

n,l=map(int, input().split())

array=[list(map(int, input().split())) for _ in range(n)]

# 행별 열별로 길을 뽑아 내어 하나의 함수에서 해결할 수 있게 route 배열을 둠
route=[]
for i in range(n):
    route.append(array[i])

for i in range(n):
    temp=[]
    for j in range(n):
        temp.append(array[j][i])
    route.append(temp)

# 길 하나가 유효한 길인지 확인하는 함수를 만듬
def check(temp):
    # 경사로를 놓은 곳은 TRUE 아닌 곳은 FALSE
    flag=[False]*len(temp)
    # 배열 전체를 돌면서
    for i in range(len(temp)-1):
        # 현재 수와 다음 수가 같으면 continue
        if temp[i]==temp[i+1]:
            continue
        # 현재수가 다음수보다 1크면, 현재 수 기준 오른쪽에 경사로를 두어야 되므로
        elif temp[i]==(temp[i+1]+1):
            if i+l<n:
                # 먼저 오른쪽 l크기만큼에 이미 경사로가 있는지 확인하고
                if True in flag[i+1:i+l]:
                    return False
                # 오른쪽 l개의 높이가 전부 같다면 경사로를 둠
                if sum(temp[i+1:i+1+l])==(temp[i+1]*l):
                    for j in range(i+1, i+l+1):
                        flag[j]=True
                # 그리고 만약에 l개의 높이 중 다른 것이 하나라도 있으면 false를 return
                else:
                    return False
            # 경사로를 놓아야 하는데 배열의 범위가 넘어갈 때도 false를 return
            else:
                return False
        # 현재수가 다음수보다 1작은 경우도 동일
        elif temp[i]==(temp[i+1]-1):
            if i-l+1>=0:
                if True in flag[i-l+1:i+1]:
                    return False
                if sum(temp[i-l+1:i+1])==(temp[i]*l):
                    for j in range(i-l+1,i+1):
                        flag[j]=True
                else:
                    return False
            else:
                return False
        else:
            return False
    return True

count=0
for i in range(len(route)):
    if check(route[i]):
        count+=1
print(count)