[코테] dx, dy 테크닉(2)
in Study / Coding Test
dx,dy 테크닉
- dx, dy 테크닉을 이용해 격자에서의 이동을 간결하게 구현하는 방법을 배움
격자에서의 dx, dy
- 격자는 2차원 배열로 표현 가능하다.
i/j 0 1 2 3 4 --------------- 0| 0 0 0 1 0 1| 0 1 1 1 0 2| 0 0 0 0 1 3| 1 0 1 1 1 4| 1 0 1 1 0
- 격자에서 dx, dy 테크닉을 이용하려면 격자에서의 x, y는 행, 열로 생각해야 한다
- zip 함수를 사용해서 각 방향에 대해 dx, dy의 쌍을 가져다 쓴다.
- zip 함수 : 넘긴 인자에 list나 tuple 같이 순회가 가능한 변수를 여러 개 넘기면 순서대로 첫 번째 원소부터 끝 원소까지 쌍으로 값을 뽑아주는 함수
for elem1, elem2 in zip(arr1, arr2)
- in_range 함수을 사용해서 (x,y)가 격자 안에 들어오면 true, 그렇지 않으면 false를 반환하도록 한다.
- 격자 안에서 벗어나면 Runtime Error가 발생하기 때문
def in_range(x, y): return 0 <= x < 5 and 0 <= y < 5
- 격자 안에서 벗어나면 Runtime Error가 발생하기 때문
- 5 * 5 크기의 격자가 주어질 때, (3행, 2열) 위치의 인접한 상하좌우 칸에 숫자 1이 몇 개 있는가?
x, y = 2, 1 dxs, dys = [0, 1, 0, -1], [1, 0, -1, 0] # in_range 함수 사용해서 (x,y)가 격자 안에 들어오는 지 판단 def in_range(x, y): return 0 <= x < 5 and 0 <= y < 5 cnt = 0 # zip 함수 사용 for dx, dy in zip(dxs, dys): nx, ny = x + dx, y + dy if in_range(nx, ny) and a[nx][ny] == 1: cnt += 1 print (cnt)
- 여기서 주의할 건 만약
if a[nx][ny] == 1 and in_range(nx, ny)
가 되면 (nx, ny)가 격자를 벗어났음에도 값이 1인지를 확인하게 된다. (Runtime Error 발생)
범위를 확인하는 조건의 경우, 항상 if문 가장 앞에 작성하는 것이 중요!
- 여기서 주의할 건 만약
문제
숫자 0과 1로만 이루어진 n * n 크기의 격자 상태가 주어집니다. 각 칸 중 상하좌우로 인접한 칸 중 숫자 1이 적혀 있는 칸의 수가 3개 이상인 곳의 개수를 세는 프로그램을 작성해보세요. 단, 인접한 곳이 격자를 벗어나는 경우에는 숫자 1이 적혀있지 않은 것으로 생각합니다.
입력 형식
첫 번째 줄에 n이 주어집니다.
두 번째 줄부터는 n개의 줄에 걸쳐 각 줄마다 각각의 행에 해당하는 n개의 숫자가 공백을 사이에 두고 주어집니다. 전부 0과 1로 이루어져 있다고 가정해도 좋습니다.
- 1 ≤ n ≤ 100
출력 형식
인접한 칸에 숫자 1이 3개 이상 적혀있는 서로 다른 칸의 수를 출력합니다.
입출력 예제
입력:
4
0 1 0 1
0 0 1 1
0 1 0 1
0 0 1 0
출력:
4
✔️ 문제 풀이
n = int(input())
arr = [
list(map(int, input().split()))
for _ in range(n)
]
ans = 0
dxs, dys = [0, 1, 0, -1], [1, 0, -1, 0]
def in_range(x, y):
return 0 <= x < n and 0 <= y < n
for x in range(n):
for y in range(n):
cnt = 0
for dx, dy in zip(dxs, dys):
nx, ny = x + dx, y + dy
if in_range(nx, ny) and arr[nx][ny] == 1:
cnt += 1
if cnt >= 3:
ans += 1
print(ans)
dx, dy 테크닉과 범위를 제한하는 in_range() 함수를 사용해서 (x,y)값의 (nx, ny)가 격자의 범위 내에 있으며, 해당 값이 1인 경우 cnt를 1씩 증가하도록 구현하였다. cnt가 3 이상이면 ans는 1씩 증가하며, 최종적으로 ans를 출력한다.
- 개선할 부분
cnt를 리턴하는 함수를 따로 작성하는 게 깔끔할 거 같다.def adjacent_cnt(x, y) : cnt = 0 for dx, dy in zip(dxs, dys): nx, ny = x + dx, y + dy if in_range(nx, ny) and arr[nx][ny] == 1: cnt += 1 return cnt for x in range(n): for y in range(n): if adjacent_cnt(x, y) >= 3: ans += 1 print(ans)
문제출처: 코드트리의 문제 및 풀이를 정리한 내용입니다.