Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Week5] 전현수 : 미로만들기, 쿼드트리, 흙길 보수하기 #26

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions src/5week/미로만들기.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package `5week`

import kotlin.math.absoluteValue

class 전현수_미로만들기{

/**
* <문제>
* [미로 만들기](https://www.acmicpc.net/problem/1347)
*
* 홍준이는 미로안의 한 칸에 남쪽을 보며 서있다.
* 미로는 직사각형 격자모양이고, 각 칸은 이동할 수 있거나, 벽을 포함하고 있음.
* 모든 행과 열에는 적어도 하나의 이동할 수 있는 칸이 있다.
* 홍준이는 모든 칸을 걸어다녔고, 자기가 걸어다닌 움직임을 노트에 적었음.
* F는 앞으로 한 칸, L, R은 왼쪽 혹은 오른쪽으로 전환.
*
* 아이디어 - 사람을 객체로 만들고 구현을 해보자?..
*/

class Hyunsoo {

// 하좌상우
// 오른쪽이면 +1, 왼쪽이면 - 1
private val directionsList = listOf(
Position(1, 0),
Position(0, -1),
Position(-1, 0),
Position(0, 1),
)

private var curDir = 0
private var moveCnt = 0
private var lastPosition = Position(0, 0)
private val visitedList = mutableListOf(Position(0, 0))

fun move() {
val newPosition = lastPosition + directionsList[curDir]
visitedList.add(newPosition)
lastPosition = newPosition
moveCnt++
}

fun turnLeft() {
if (curDir == 0) {
curDir = 3
} else {
curDir--
}
}

fun turnRight() {
if (curDir == 3) {
curDir = 0
} else {
curDir++
}
}

fun getVisitedList() = visitedList.toList()

fun getMapSize() = visitedList.minOf { it.comparator() }
}

data class Position(val x: Int, val y: Int) {

operator fun plus(position: Position): Position {
return this.copy(
x = this.x + position.x,
y = this.y + position.y
)
}

fun comparator(): Int =
if (this.x < this.y) this.x else this.y

}

enum class Command {
L,
R,
F
}

fun solution() {

val commandCnt = readln().toInt()
val commandList = readln().chunked(1)
val hyunsoo = Hyunsoo()

commandList.forEach { command ->
when (command) {
Command.L.name -> {
hyunsoo.turnLeft()
}

Command.R.name -> {
hyunsoo.turnRight()
}

Command.F.name -> {
hyunsoo.move()
}
}
}

val mapSize = hyunsoo.getMapSize().absoluteValue
val mapData = Array(51) {
Array(51) { "#" }
}

var startXIndex = Int.MAX_VALUE
var startYIndex = Int.MAX_VALUE
var endXIndex = 0
var endYIndex = 0

hyunsoo.getVisitedList().forEach { pos ->
val x = pos.x + mapSize
val y = pos.y + mapSize

if (startXIndex > x) startXIndex = x
if (startYIndex > y) startYIndex = y
if (endXIndex < x) endXIndex = x
if (endYIndex < y) endYIndex = y
mapData[x][y] = "."
}

for (x in startXIndex..endXIndex) {
for (y in startYIndex..endYIndex) {
print(mapData[x][y])
}
println()
}

}

}
71 changes: 71 additions & 0 deletions src/5week/쿼드트리.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package `5week`

class 전현수_쿼드트리 {

/**
* <문제>
* [쿼드트리](https://www.acmicpc.net/problem/1992)
*
* 분할정복?
*
* 단계
* - 현재 영역이 0, 1 단일로만 구성되어있는지 확인해보기
* - 단일로만 구성되어있다면
* - 0, 1로 압축하기
* - 4등분 하기
* - 각 등분 별로 단계 처음부터 반복
* -
*/
fun solution() {

val size = readln().toInt()
val imageData = Array<String>(size) { readln() }
divideAndConquer(imageData.toList()).apply {
println(this)
}

}

fun divideAndConquer(imageData: List<String>): String {

// 단일 숫자로만 구성되었는지 확인하기
var isSingle = true
val firElement = imageData.first().first()
imageData.forEach { string ->
if (string.any { it != firElement }) isSingle = false
}

// 단일이라면
if (isSingle) {
return "$firElement"
// 단일이 아니라면, 4분할 후 각각 재귀
} else {

val size = imageData.size
val halfSize = size / 2

// 좌상 우상 좌하 우하
val firstArea = imageData.subList(0, halfSize).map {
it.substring(0, halfSize)
}
val secondArea = imageData.subList(0, halfSize).map {
it.substring(halfSize, size)
}
val thirdArea = imageData.subList(halfSize, size).map {
it.substring(0, halfSize)
}
val fourthArea = imageData.subList(halfSize, size).map {
it.substring(halfSize, size)
}

val leftTop = divideAndConquer(firstArea)
val rightTop = divideAndConquer(secondArea)
val leftBottom = divideAndConquer(thirdArea)
val rightBottom = divideAndConquer(fourthArea)

return "($leftTop$rightTop$leftBottom$rightBottom)"
}

}

}
49 changes: 49 additions & 0 deletions src/5week/흙길 보수하기.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package `5week`

class 전현수_흙길_보수하기 {

/**
* <문제>
* [흙길 보수하기](https://www.acmicpc.net/problem/1911)
*
* 범위 보니까 이거 이분 탐색이네??...
* -> 아니네...
*
* 스위핑?
*
* 입/출력
* - 첫째 줄에 물웅덩이의 개수(N)과 물웅덩이를 덮을 수 있는 널빤지의 길이(L)가 주어짐.
* - 웅덩이의 정보가 주어짐. 웅덩이의 정보는 웅덩이의 시작 위치와 끝 위치로 이루어짐.
*/

data class Puddle(val start: Int, val end: Int)

fun solution() {

val (puddleCnt, plankLength) = readln().split(" ").map { it.toInt() }
// 널빤지의 끝 위치가 담길 변수
var lastPlankLocation = 0
var needPlankCnt = 0

val puddleArray = Array(puddleCnt) {
val (start, end) = readln().split(" ").map { it.toInt() }
Puddle(start, end)
}

puddleArray.sortWith(compareBy<Puddle> { it.start }.thenBy { it.end })


puddleArray.forEach { puddle ->
lastPlankLocation = if (puddle.start < lastPlankLocation) lastPlankLocation else puddle.start
val end = puddle.end

while (lastPlankLocation < end) {
lastPlankLocation += plankLength
needPlankCnt++
}
}

println(needPlankCnt)
}

}