2차원 배열의 모든 요소에 대해 각각 상하좌우 + 대각선 방향(총 8번)의 칸을 모두 순회한다.
import sys
N, K = map(int, input().split())
maps = [[0] * (N + 2) for _ in range(N + 2)]
for i in range(N):
row = list(map(int, sys.stdin.readline().split()))
for j in range(N):
maps[i + 1][j + 1] = row[j]
answer = 0
for i in range(1, N + 1):
for j in range(1, N + 1):
# 구름칸
if maps[i][j]:
continue
if maps[i - 1][j - 1] + maps[i - 1][j] + maps[i - 1][j + 1] \
+ maps[i][j - 1] + maps[i][j + 1] \
+ maps[i + 1][j - 1] + maps[i + 1][j] + maps[i + 1][j + 1] == K:
answer += 1
print(answer)
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int N, K;
int arr[1000][1000] = {0};
cin >> N >> K;
for (int i = 0; i < N; i++){
for (int j = 0; j < N; j++){
cin >> arr[i][j];
}
}
int tot_flag_cnt = 0;
pair<int, int> dirs[8] = {make_pair(0, 1), make_pair(-1, 1),
make_pair(-1, 0), make_pair(-1, -1),
make_pair(0, -1), make_pair(1, -1),
make_pair(1, 0), make_pair(1, 1)};
for (int y = 0; y < N; y++){
for (int x = 0; x < N; x++){
int flag_cnt = 0;
if (arr[y][x] == 1)
continue;
for (int n = 0; n < 8; n++){
int dy = dirs[n].first, dx = dirs[n].second;
int ny = y + dy, nx = x + dx;
if (ny < 0 || ny == N || nx < 0 || nx == N)
continue;
if (arr[ny][nx] == 1)
flag_cnt++;
}
if (flag_cnt == K)
tot_flag_cnt++;
}
}
cout << tot_flag_cnt;
return 0;
}

# 1칸씩 이동할 때만 사용 가능
if y in (-1, N) or x in (-1, N):
continue
dy = [-1, -1, 0, 1, 1, 1, 0, -1] # 반시계 방향
dx = [0, -1, -1, -1, 0, 1, 1, 1]
for k in range(8):
y = i + dy[k]
x = j + dx[k]
배열의 크기는 컴파일 시 결정이 되어야 한다. int로 지정하면 에러가 발생하지만, const로 상수 선언을 하면 에러 없이 사용할 수 있다.
const int MAX = 1004;
int board[MAX][MAX];
'구간 합'에 꽂혀서 2차원 리스트를 더하려고 궁리하다보니, 8개 요소를 하드코딩으로 더하는 결과가 나왔다. 해답으로 다른 풀이법을 확인할 수 있는 점이 구름톤 챌린지의 1순위 장점이라고 생각한다.