Loading [MathJax]/jax/output/CommonHTML/jax.js
본문 바로가기

알고리즘/구름톤 챌린지

[구름톤 챌린지] 2주차 7일차 구름 찾기 깃발

728x90

 

 

문제


구름 찾기 게임은 한 변의 길이가 N인 격자 모양의 게임판 M에서 진행하는 게임이다. 게임판의 일부 칸에는 구름이 숨겨져 있고, 게임판에 숨겨진 모든 구름의 위치를 찾으면 게임에서 승리할 수 있다.

구름 찾기 게임의 제작자인 플레이어는 조금 더 쉽게 구름을 찾을 수 있도록 도와주는 깃발을 게임판 위에 설치하려고 한다. 깃발은 구름이 없는 칸이면서, 상하좌우와 대각선으로 인접한 여덟 칸 중 구름이 하나 이상 있는 칸에만 설치할 수 있다. 이렇게 설치한 깃발에는 인접한 여덟 칸 중 구름이 있는 칸의 개수에 해당하는 값이 적힌다.

플레이어는 깃발을 세울 수 있는 모든 칸에 깃발을 세워두었다. 문득, 플레이어는 깃발 중 값이 K인 깃발이 몇 개나 있는지가 궁금해졌다. 여러분이 플레이어를 대신해 값이 K인 깃발의 개수를 세어주자.

예제 설명


첫 번째 예제에서 주어지는 게임판은 다음과 같다. 편의상 게임판의 r번째 행, c번째 열에 해당하는 칸을 Mr,c와 같이 나타낸다고 하자.

 

M3,2는 구름이 없는 칸이면서, 동시에 주변 여덟 칸 중 구름이 있기 때문에 깃발을 설치할 수 있다. 네 개의 구름이 있으므로 깃발의 값은 4가 된다.

 

게임판의 가능한 모든 위치에 깃발을 설치했을 때의 결과는 아래와 같다. 비어있는 칸은 깃발을 설치하지 않은 칸이다.

 

입력


첫째 줄에 게임판의 크기 N과 찾고 싶은 깃발의 값 K가 공백을 두고 주어진다.
다음 N개의 줄에는 게임판의 각 칸에 대한 정보가 N개의 문자로 공백을 두고 주어진다. r번째 줄에서 c번째로 주어지는 문자는 Mr,c칸에 해당하는 정보이다. 0은 그 칸이 비어있음을, 1은 그 칸에 구름이 숨겨져 있음을 의미한다.

 

  • 1N1 000
  • 1K8
  • N과 K는 모두 정수이다.
  • 각 칸의 정보를 나타내는 문자는 0 또는 1 중 하나이다.

출력


값이 K인 깃발의 개수를 출력한다.

 


문제 접근 방식


브루트 포스로 모든 칸들을 확인해가며, 각 칸 마다 주위 8칸을 보는 방식을 취했다.

 

이때, 칸들을 확인할 때 구름이 없는 칸에만 깃발을 꽃을 수 있으므로, 구름이 없는 0일때에만 주위 8칸을 탐색해주었다.

 

이때, 주위 8칸의 범위 또한 신경 써주면서 탐색을 진행했다.

 

주위 8칸에 있는 구름의 개수를 세어서, 이 개수가 만약 K와 같으면 우리가 원하는 깃발의 값이 적혀있는 것이라고 판단할 수 있으므로, 이때 답에 +1을 해준다.

 

이 과정을 거쳐서 최종적으로 나온 답을 출력해주었다.

 


정답 코드


# 구름 찾기 깃발
import sys
input = sys.stdin.readline

N, K = map(int, input().rstrip().split())
matrix = [list(map(int, input().rstrip().split())) for _ in range(N)]
flag = 0
dr = [-1, -1, -1, 0, 0, 1, 1, 1]
dc = [-1, 0, 1, -1, 1, -1, 0, 1]
for i in range(N):
    for j in range(N):
        if matrix[i][j]:
            continue
        cnt = 0
        for k in range(8):
            ni, nc = i+dr[k], j+dc[k]
            if 0 <= ni < N and 0 <= nc < N and matrix[ni][nc]:
                cnt += 1
        if cnt == K:
            flag += 1
print(flag)

 


특별히 배운 점


유명한 지뢰찾기류 문제이기 때문에 좀 더 효율적인 구현이 가능했을 수도 있을 것 같다.