[깃허브]
https://github.com/heesoo-park/ForCodeKata/tree/main/baekjoon%20%EB%AC%B8%EC%A0%9C%EC%A7%91/N-Queen
[백준]
https://www.acmicpc.net/problem/9663
어떻게 하다보니 어제 풀었던 문제랑 동일한 문제를 풀게 되었다.
그런데 왜 이렇게 시간차이가 많이 나는지...? 이상했지만 보니까 백준은 14까지, 프로그래머스는 12까지였다.
거기에서 온 차이가 아닐까 싶다.
그래도 여기서 시간을 더 줄이기위해 노력한 부분은 분명히 있었다.
전에는 위쪽 대각선도 생각하고 처리를 했었는데 생각해보면 위에서부터 차례대로 내려오기 때문에 처리할 필요가 없었다.
이 부분 제거했고 첫번째 줄에 대한 처리도 재귀함수에 넣는 방식을 채택했다.
이렇게 푸니까 약간 복습하는 것 같아서 좋았지만 다른 사람들이 많이 푸는 방식은 아직 이해가 잘 안되더라
1차원 배열로 푸는 방식인데 인덱스가 행, 값이 열이 되고 지금 놓은 자리가 놔도 괜찮은 자리인지 체크하는 알고리즘이었다.
앞의 배열에 값을 지정하는 건 이해가 잘 됐는데 지금 놓은 자리가 놔도 괜찮은 자리인지 체크하는 방식은 아직 잘 이해가 되지 않는다.
행을 돌면서 열의 값이 같거나 행끼리의 차이의 절댓값과 열끼리의 차이의 절대값이 같다면 false를 리턴하고 아니면 true를 리턴한다.
가로체크는 당연히 그 전까지의 행만 순회하면되니까 오케이
세로체크는 열의 값 체크로 오케이
대각선체크가 조금... 잘 이해가 안 되네
그래도 어느정도 느낌이 이제 오는건 대각선이라는거는, 특히 지금 문제에서 원하는 대각선이라는 거는 가로세로 길이의 비율이 1대1인 두변을 가지는 대각선이기 대문에 차이의 절대값을 비교하는 것 같다.
이렇게 푸는 거 또 나중에 기회가 있겠지...
잘 기억하고 있어야겠다.
2차원 배열을 만드는 것이 아니라 1차원 배열에 행과 열의 정보를 넣는 방식..!!
배열의 값을 바꿀 때 약간 이슈가 있었는데 forEach로 배열을 순회하면서 조건에 맞을 때 해당 위치의 값을 바꾸려고 하니까 Val cannot be reassigned 에러가 뜨더라
그 이유는 실제 데이터가 아닌 참조만 할 수 있는 형태로 it을 사용하기 때문인 거 같다.
이걸 해결하기 위해서는 인덱스를 도는 형태인 for문을 사용하면 됐다.
해당 방법으로 작성한 코드는 다음과 같다.
private lateinit var chessBoard: Array<Array<Int>>
private var n = 0
private var answer = 0
fun main() = with(System.`in`.bufferedReader()) {
n = readln().toInt()
chessBoard = Array(n) { Array(n) { 0 } }
deployQueen(0)
println(answer)
}
fun deployQueen(row: Int) {
if (row == n) {
answer++
return
}
for (i in 0 until n) {
if (chessBoard[row][i] == 0) {
setAttachRange(row, i)
deployQueen(row + 1)
deleteAttackRange(row)
}
}
}
fun setAttachRange(row: Int, col: Int) {
for (i in chessBoard.indices) {
if (chessBoard[row][i] == 0) chessBoard[row][i] = -(row + 1)
if (chessBoard[i][col] == 0) chessBoard[i][col] = -(row + 1)
}
var r = 1
var c = 1
while (row + r < n && col + c < n) {
if (chessBoard[row + r][col + c] == 0) chessBoard[row + r][col + c] = -(row + 1)
r++; c++
}
r = 1
c = 1
while (row + r < n && col - c >= 0) {
if (chessBoard[row + r][col - c] == 0) chessBoard[row + r][col - c] = -(row + 1)
r++; c++
}
}
fun deleteAttackRange(row: Int) {
for (i in 0 until n) {
for (j in 0 until n) {
if (chessBoard[i][j] == -(row + 1)) chessBoard[i][j] = 0
}
}
}
'Kotlin > Algorithm Problems' 카테고리의 다른 글
<프로그래머스> 24.02.21 복습 (0) | 2024.02.21 |
---|---|
<프로그래머스> 24.02.20 복습 (0) | 2024.02.21 |
<프로그래머스> N-Queen(Lv.2) (0) | 2024.02.13 |
<프로그래머스> 두 원 사이의 정수 쌍(Lv.2) (1) | 2024.02.07 |
<백준> A와 B(Gold 5) (0) | 2024.02.06 |