๐ ๋ฌธ์
๐ง ์์ด๋์ด
์คํฐ์ปค๋ฅผ ํฌํจํ ๋ชจ๋ ๋ชจ๋ ์ข ์ด๋ ๊ฒฐ๊ตญ ์ง์ฌ๊ฐํ ํํ๋ค.
๋ฐํ์ด ๋ ๋ ธํธ๋ถ ๋ชจ๋์ข ์ดํ์ 'noteBookTable' ์คํฐ์ปค ์กฐ๊ฐ๋ค์ 'sticker' ๋ผ๊ณ ํ๋ฉด
1. ์คํฐ์ปค ๋ถ์ด๊ธฐ ๊ฐ๋ฅ ๋ถ๊ฐ๋ฅ ์ฌ๋ถ ํ๋ณ๋ฒ
๋ค์ 4๊ฐ์ง ์ผ์ด์ค๊ฐ ์กด์ฌํ๋ค.
- โ๏ธnoteBookTable ์์๋ 0 (๋น์ด์๊ณ ) sticker ์์๋ 1 (์คํฐ์ปค)
- โ๏ธnoteBookTable ์์๋ 1 (์ด๋ฏธ ๋ค๋ฅธ ์คํฐ์ปค๊ฐ ๋ถ์ด์๊ณ ) sticker ์์๋ 0 (๊ณต๋ฐฑ)
- โ๏ธnoteBookTable ๋ 0 (๋น์ด์๊ณ ) sticker ์์๋ 0
- โnoteBookTable ์์ 1 (์ด๋ฏธ ๋ค๋ฅธ ์คํฐ์ปค๊ฐ ๋ถ์ด์๊ณ ) sticker ์์๋ 1 (์คํฐ์ปค)
์ ์ผ์ด์ค์ค 1,2,3 ๋ฒ๋ง ์คํฐ์ปค ๋ถ์ด๊ธฐ๊ฐ ๊ฐ๋ฅํ ์ผ์ด์ค๋ค.
noteBookTable๊ณผ sticker๊ฐ 0-1, 1-0, 0-0 ๊ด๊ณ์ฌ์ผ ํ๋ฏ๋ก NOR ์ฐ์ฐ์ด true ๋ฉด ๋ถ์ผ ์ ์๋ ๊ณต๊ฐ์ด๋ค.
์ฆ ๊ฐ์ noteBookTable ๊ณผ sticker ์ฌ์ด์ ๋ชจ๋ ๊ณต๊ฐ์ด NOR == true ๋ฉด ์คํฐ์ปค ๋ถ์ด๊ธฐ๊ฐ ๊ฐ๋ฅํ๋ค.
2. ์คํฐ์ปค๋ฅผ ์ด๋์ ๋ถ์ผ์ง ์ด๋ป๊ฒ ๊ฒฐ์ ํ ์ ์์๊น?
์ฐ์ , sticker ์ ๊ฐ๋ก ๋๋ ์ธ๋ก ๊ธธ์ด๊ฐ noteBookTable ๋ณด๋ค ๋ ๊ธด ๊ฒฝ์ฐ ๋ฌด์กฐ๊ฑด ์คํจ๋ค.
์ง์ฌ๊ฐํ์ ๋งจ ์ผ์ชฝ ์์นธ์ธ (0,0) ์ ์์์ผ๋ก ํ์นธ์ฉ ์ด๋ํ๋ฉด์ ๋ถ์ฌ๋ณด๋ ์ ๋ฐ์ ์๋ค. => Backtracking ์ผ๋ก ์ ๊ทผํ๋ค.
(์คํฐ์ปค๋ ๊ฐ๋ฅํ ์ข์ธก ์๋จ๋ถํฐ ๋ถ์ธ๋ค๊ณ ์ค๋ช ๋์ด์๋ค.)
3. ๋ ธํธ๋ถ - ์คํฐ์ปค ์กฐ๊ฐ ๋น๊ต๋ฅผ ์ํ ์กฐ๊ฐ ๋ง๋ค๊ธฐ
๋
ธํธ๋ถ ๋ชจ๋์ข
์ด์ ์คํฐ์ปค ์กฐ๊ฐ์ ๊ฐ๋ก ์ธ๋ก ๊ธธ์ด๊ฐ ๋ค๋ฅด๋ฏ๋ก ๊ฐ์ ๊ธธ์ด์ ์กฐ๊ฐ์ ์ถ์ถํด์ ๋น๊ตํด์ฃผ์.
์ด ๋, ๋ชจ๋์ข
์ด์์ ์ถ์ถํ ์ ์๋ ๊ฐ๋ก ์ธ๋ก ๊ธธ์ด๊ฐ ์คํฐ์ปค๋ณด๋ค ์์ ๊ฒฝ์ฐ ํด๋น ์กฐ๊ฐ ์์ฑ์ skip ํ๋ค.
2์ฐจ์ ๋ฐฐ์ด์ ๋ณต์ฌํ ๋ ์ฃผ์ํ ์ ์ ์ฌ๊ธฐ์์ ํ์ธํ ์ ์๋ค.
// ๋์ผํ ๋
ธํธ๋ถ ๋ชจ๋์ข
์ด๋ก๋ถํฐ ์คํฐ์ปค ํฌ๊ธฐ์ ๋์ผํ ์ฌ์ด์ฆ์ ์ง์ฌ๊ฐํ ์ถ์ถ
private fun makePartialNoteBook(
startRow: Int,
startCol: Int,
noteBookTable: Array<IntArray>,
sticker: Array<IntArray>
): Array<IntArray> {
val stickerRowSize = sticker.size
val stickerColSize = sticker.first().size
return Array(stickerRowSize) { idx ->
// ํด๋น ๋
ธํธ๋ถ์ ์์์ง์ ์ผ๋ก๋ถํฐ ๋ถ์ผ ์คํฐ์ปค์ ํฌ๊ธฐ๋งํผ์ ๋ฐฐ์ด์ ํต์งธ๋ก ๋ณต์ฌํ๋ค.
noteBookTable[idx + startRow].copyOfRange(
startCol,
startCol + stickerColSize
)
}
}
4. ์คํฐ์ปค ์กฐ๊ฐ 90๋ ํ์
2์ฐจ์ ๋ฐฐ์ด (ํ๋ ฌ) ํ์ ๋ฐฉ๋ฒ์ ์ฌ๊ธฐ์ ์ ๋ฆฌํด๋์๋ค.
// ์คํฐ์ปค ๋ฐฐ์ด 90๋ ํ์ ํ ๋ฐํ
private fun rotateSticker(sticker: Array<IntArray>): Array<IntArray> {
val originalRowSize = sticker.size
val originalColSize = sticker.first().size
val rotatedSticker = Array(originalColSize){IntArray(originalRowSize)}
for (row in sticker.indices) {
for (col in sticker[0].indices) {
rotatedSticker[col][row] = sticker[originalRowSize - 1 - row][col]
}
}
return rotatedSticker
}
5. ์คํฐ์ปค ๋ถ์ด๊ธฐ
์ 1,2,3,4 ์์ด๋์ด๋ก ์คํฐ์ปค ๋ถ์ด๊ธฐ๊ฐ ๊ฐ๋ฅํ ์ผ์ด์ค๋ฅผ ๋ง๋ฌ์ ๋, ๋ชจ๋์ข ์ด ์๋ณธ์ ์์น ํด์ฃผ๋ ์์ ์ด ํ์ํ๋ค.
ํด๋น ์์ ์ง์ ์ผ๋ก๋ถํฐ ์์ฑํ๋ ์กฐ๊ฐ ํฌ๊ธฐ๋งํผ์ ๋ฒ์๋ฅผ ์ก์ OR์ฐ์ฐ ๊ฒฐ๊ณผ๊ฐ์ ๋ถ์ฌ๋ฃ๋๋ค.
6. 1~5๋ฅผ ๋ฐ๋ณตํ๋ผ, ์ธ์ ๊น์ง?
๋ชจ๋ ์คํฐ์ปค ๋ถ์ด๊ธฐ๋ฅผ ์๋ํด๋ณด๊ธฐ๊น์ง
๊ฐ ์๋ฆฌ๋ฅผ ๋ชจ๋ ํ์ํ ํ์ 90๋ ํ์ ํ ์ฌ์๋ํด์ผํ๋ค.
ํ ์๋ฆฌ์์ 90, 180, 270๋๋ฅผ ๋ชจ๋ ํ์ ์์ผ๋ณด๋๊ฒ ์๋๋ค.
๋ฌธ์ ๋ฅผ ๊ผผ๊ผผํ ์ฝ์ง ์๊ณ ์๋ฆฌ๋ฅผ ์ด๋ํ๋ฉฐ (0๋, 90๋, 180๋, 270๋) ํ์ ์์ผ๋ณด๋ฉฐ ๋์ ํ๋ค๊ฐ ๊ณ์ ํ๋ ธ๋ค.
"ํ ์คํธ์ผ์ด์ค๋ ๋ค ๋ง๋๋ฐ ์ ๋ญ๊ฐ ๋ฌธ์ ์ง?" ํ๋ฉด์ ํค๋ฉ๋ค๊ฐ ๋ฌธ์ ๋ฅผ ๋ค์ ์ฝ๊ณ ์์๋ค..
๐ Kotlin Code
import java.io.BufferedReader
import java.io.InputStreamReader
import java.util.*
private fun isOutOfBoundPartialTable(startRow: Int, startCol: Int, noteBookTable: Array<IntArray>, sticker: Array<IntArray>) : Boolean {
val stickerRowSize = sticker.size
val stickerColSize = sticker.first().size
return startRow + stickerRowSize > noteBookTable.size || startCol + stickerColSize > noteBookTable.first().size
}
// ๋์ผํ ๋
ธํธ๋ถ ๋ชจ๋์ข
์ด๋ก๋ถํฐ ์คํฐ์ปค ํฌ๊ธฐ์ ๋์ผํ ์ฌ์ด์ฆ์ ์ง์ฌ๊ฐํ ์ถ์ถ
private fun makePartialNoteBook(
startRow: Int,
startCol: Int,
noteBookTable: Array<IntArray>,
sticker: Array<IntArray>
): Array<IntArray> {
val stickerRowSize = sticker.size
val stickerColSize = sticker.first().size
return Array(stickerRowSize) { idx ->
noteBookTable[idx + startRow].copyOfRange(
startCol,
startCol + stickerColSize
)
}
}
private fun isAttachable(partialTable: Array<IntArray>, sticker: Array<IntArray>) : Boolean {
for (row in partialTable.indices) {
for (col in partialTable[row].indices) {
// nor ์ด false ๋ฉด ์คํฐ์ปค ๋ถ์ด๊ธฐ ๋ถ๊ฐ๋ฅ == ๋๋ค ์ด๋ฏธ ์ฑ์์ ธ์๋ ์นธ์ด๋ฉด
if (partialTable[row][col] == 1 && sticker[row][col] == 1) return false
}
}
// nor ์ฐ์ฐ ๋ชจ๋ ํต๊ณผ์ ์คํฐ์ปค ๋ถ์ด๊ธฐ ๊ฐ๋ฅ.
return true
}
private fun rotateSticker(sticker: Array<IntArray>): Array<IntArray> {
val originalRowSize = sticker.size
val originalColSize = sticker.first().size
val rotatedSticker = Array(originalColSize){IntArray(originalRowSize)}
for (row in sticker.indices) {
for (col in sticker[0].indices) {
rotatedSticker[col][row] = sticker[originalRowSize - 1 - row][col]
}
}
return rotatedSticker
}
fun main() {
val bufferedReader = BufferedReader(InputStreamReader(System.`in`))
val (N, M, K) = bufferedReader.readLine().split(" ").map(String::toInt)
// ๋น ๋
ธํธ๋ถ ํ
์ด๋ธ ์์ฑ
val noteBookTable = Array(N){IntArray(M)}
val stickerTable = LinkedList<Array<IntArray>>()
// ์คํฐ์ปค ์์ฑ
for (i in 1 .. K) {
val (rowSize, colSize) = bufferedReader.readLine().split(" ").map(String::toInt)
val sticker = Array(rowSize){_->
bufferedReader.readLine().split(" ").map(String::toInt).toIntArray()
}
stickerTable.add(sticker)
}
// ์คํฐ์ปค ํ๋์ฉ ๊บผ๋ด์ ๋น๊ต
for (sticker in stickerTable) {
var isPasted = false
var rotatedSticker = sticker
for (repeatNum in 1 .. 4) {
// ์์์ขํ ๊ตฌํ๋ ๊ณผ์ ์์ 1ํ๋ผ๋ ์คํฐ์ปค ๋ถ์ด๊ธฐ ์ฑ๊ณต์ ํ์ถ (break)
for (row in noteBookTable.indices) {
if (isPasted) break
for (col in noteBookTable[0].indices) {
// ์ถ์ถ์ด ๊ฐ๋ฅํ ํฌ๊ธฐ์ ์คํฐ์ปค์ธ์ง
if (isOutOfBoundPartialTable(row, col, noteBookTable, rotatedSticker)) continue
// ์๋ณธ ๋ชจ๋์ข
์ด ์กฐ๊ฐ ์์ฑ
val partTable = makePartialNoteBook(row, col, noteBookTable, rotatedSticker)
// ์คํฐ์ปค ๋ถ์ด๊ธฐ ๊ฐ๋ฅ์ฌ๋ถ ํ์ธ
if(!isAttachable(partTable, rotatedSticker)) continue
// ์คํฐ์ปค ๋ถ์ด๊ธฐ
for (i in row until row + rotatedSticker.size) {
for (j in col until col + rotatedSticker[0].size) {
// OR ์ฐ์ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋๋ก ๋ถ์ฌ๋ฃ์.
noteBookTable[i][j] = noteBookTable[i][j] or rotatedSticker[i - row][j - col]
}
}
// ๋ถ์ด๊ธฐ๊ฐ ์๋ฃ๋๋ฉด ๋ค์ ์คํฐ์ปค๋ก ์ด๋
isPasted = true
break
}
}
// ๋์ค์ ์คํฐ์ปค ๋ถ์ด๊ธฐ ์ฑ๊ณต์ ๋ค์ ํ์ loop ์์ ํ์ถ ์ฌ๊ธฐ์ ๋๋ฌํ์ง ์์.
if (isPasted) break
// 0๋ -> 90๋ -> 180๋ -> 270๋๋ก ํ์ ์ด 4ํ,
rotatedSticker = rotateSticker(rotatedSticker)
}
}
// ๋ชจ๋ ์คํฐ์ปค ๋ถ์ด๊ธฐ๊ฐ ์๋ฃ๋ ์ํ
var emptyCnt = 0
for (row in noteBookTable) {
emptyCnt += row.count{it == 0}
}
// ์ ์ฒด ๋์ด - 0์ ๊ฐ์ == ๋ถ์ฌ์ง ์คํฐ์ปค ๊ฐ์
print(N * M - emptyCnt)
}
'Algorithm > Algorithm (๋ฌธ์ ํ์ด)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[๋ฐฑ์ค] 15686 ์นํจ ๋ฐฐ๋ฌ (1) | 2022.10.10 |
---|---|
[๋ฐฑ์ค] 1504 ํน์ ํ ์ต๋จ๊ฒฝ๋ก (0) | 2022.10.07 |
[๋ฐฑ์ค] 15683 ๊ฐ์ (0) | 2022.10.03 |
[๋ฐฑ์ค] 2493 ํ (0) | 2022.10.03 |
[๋ฐฑ์ค] 2217 ๋กํ (0) | 2022.09.28 |