본문 바로가기

PS/백준

[BOJ] 백준 2578 빙고 (Swift)

반응형

문제

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

 

2578번: 빙고

첫째 줄부터 다섯째 줄까지 빙고판에 쓰여진 수가 가장 위 가로줄부터 차례대로 한 줄에 다섯 개씩 빈 칸을 사이에 두고 주어진다. 여섯째 줄부터 열째 줄까지 사회자가 부르는 수가 차례대로

www.acmicpc.net

풀이

5 * 5 개의 빙고판에서 빙고가 되는 경우가 어떤 경우인지 생각해봅시다.

  1. 가로로 모든 수가 지워진 경우
  2. 세로로 모든 수가 지워진 경우
  3. 대각선

이 3가지 경우입니다.

먼저, 5 * 5의 Bool 자료형의 2차원 배열을 false로 초기화해줍시다.

그 이후, 숫자를 key, 숫자의 좌표가 value인 Dictionary를 생성해주었습니다.

이제 빙고판에 쓰여진 수를 지울 때, 수를 입력받고, Dictionary의 key에서 value를 받아와
2차원 배열의 원소를 true로 값을 변경해주십다.

수를 지울 때 마다 3개의 빙고가 되었는지 확인해줍시다.

먼저, 가로로 빙고가 된 경우
for문을 0 ~ 4 까지 돌면서 2차원 배열에 접근해주는데,
board[i] == [true, true, true, true, true] 라면 가로로 모두 빙고가 된 것일 겁니다.

세로로 빙고가 된 경우는 어떨까요?

가장 왼쪽의 세로 빙고의 경우
board[0][0], board[1][0], board[2][0], board[3][0] board[4][0]이 모두 true인 경우겠죠?

그 뒤면
board[0][1], board[1][1] ... board[4][1] 이 true일 것입니다.

2중 중첩 for문을 사용해서 확인해 줄 수 있습니다.

다음 대각선의 경우는
board[0][0], board[1][1], board[2][2], board[3][3], board[4][4]가 모두 true인 경우
board[0][4], board[1][3], board[2][2], board[3][1], board[4][0]이 모두 true인 경우겠죠?

2중 중첩 for문을 사용할 수도 있고, 5개니깐 그냥 다 적어줘도 무방할 것입니다.

수를 입력받을 때 마다 빙고가 되는지 체크하면서 3개의 빙고가 되었을 때,
몇 번째인지 출력해주면 끝 입니다.

소스코드

var board = [[Bool]](repeating: [Bool](repeating: false, count: 5), count: 5)
var coords: [Int: (Int, Int)] = [:]
for y in 0..<5 {
let nums = readLine()!.split(separator: " ").map { Int($0)! }
for (x, num) in nums.enumerated() {
coords[num] = (y, x)
}
}
mainLoop: for y in 0..<5 {
let nums = readLine()!.split(separator: " ").map { Int($0)! }
for (index, num) in nums.enumerated() {
let coord = coords[num]!
board[coord.0][coord.1] = true
if check() {
print(y * 5 + index + 1)
break mainLoop
}
}
}
func check() -> Bool {
var count = 0
var diagonalBingo1 = true
var diagonalBingo2 = true
for i in 0..<5 {
// 가로 빙고 확인
count += board[i] == [Bool](repeating: true, count: 5) ? 1 : 0
// 세로 빙고 확인
var columnBingo = true
for j in 0..<5 {
if !board[j][i] {
columnBingo = false
}
}
count += columnBingo ? 1 : 0
// 대각선 빙고 확인
if !board[i][i] {
diagonalBingo1 = false
}
if !board[i][4 - i] {
diagonalBingo2 = false
}
}
count += diagonalBingo1 ? 1 : 0
count += diagonalBingo2 ? 1 : 0
return count > 2
}
view raw 빙고.swift hosted with ❤ by GitHub

후기

핵심은 빙고를 판별하는 로직인 것 같습니다.

사회자가 부른 수를 입력받고, 2차원 배열에서 그 수가 어디있는지 하나씩 찾아봐도 무방하지만 (빙고판의 크기가 작아서)
빙고판의 크기가 크다면 Dictionary로 수의 좌표를 저장하는 방법이 더 좋아보입니다.

반응형