From bde23f3752c4d04991804beb5efb4b45376e1ecc Mon Sep 17 00:00:00 2001 From: soopeach Date: Wed, 22 Mar 2023 13:36:58 +0900 Subject: [PATCH 1/5] =?UTF-8?q?Feat:=20=EC=97=B0=EA=B5=AC=EC=86=8C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\354\227\260\352\265\254\354\206\214.kt" | 144 ++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 "src/main/kotlin/hyunsoo/28week/\354\227\260\352\265\254\354\206\214.kt" diff --git "a/src/main/kotlin/hyunsoo/28week/\354\227\260\352\265\254\354\206\214.kt" "b/src/main/kotlin/hyunsoo/28week/\354\227\260\352\265\254\354\206\214.kt" new file mode 100644 index 00000000..95fa4887 --- /dev/null +++ "b/src/main/kotlin/hyunsoo/28week/\354\227\260\352\265\254\354\206\214.kt" @@ -0,0 +1,144 @@ +package hyunsoo.`28week` + +/** + * + * <문제> + * [연구소](https://www.acmicpc.net/problem/14502) + * + * - 아이디어 + * + * 지도의 크기가 최대 8 * 8 + * 64c3 = 41664 완탐 가능 + * + * - 트러블 슈팅 + * + */ +class `전현수_연구소` { + + private data class Position(val x: Int, val y: Int) + + private val dirs = listOf( + Position(0, 1), + Position(0, -1), + Position(1, 0), + Position(-1, 0), + ) + + private val map = mutableListOf>() + private val emptyPositions = mutableListOf() + private val installedPositions = mutableListOf() + + private var maxSafeZoneSize = 0 + + fun solution() { + val (row, column) = readln().split(" ").map { it.toInt() } + + repeat(row) { rowIndex -> + val rowData = readln().split(" ").map { it.toInt() } as MutableList + rowData.forEachIndexed { columnIndex, value -> + if (value == EMPTY) emptyPositions.add(Position(rowIndex, columnIndex)) + } + map.add(rowData) + } + + findAllCase() + + println(maxSafeZoneSize) + } + + private fun findAllCase(cnt: Int = 0, startWith: Int = 0) { + if (cnt == MAX_INSTALLED_CNT) { + // 맵 복사후 탐색 + val wallInstalledMap = map.deepCopy().apply { + installedPositions.forEach { pos -> + this[pos.x][pos.y] = 1 + } + } + + val safeZoneSize = countSafeZone(wallInstalledMap) + if (maxSafeZoneSize < safeZoneSize) maxSafeZoneSize = safeZoneSize + return + } + + for (index in startWith until emptyPositions.size) { + installedPositions.add(emptyPositions[index]) + findAllCase(cnt + 1, index + 1) + installedPositions.removeLast() + } + } + + private fun countSafeZone(map: MutableList>): Int { + + val visit = Array(map.size) { + BooleanArray(map.first().size) + } + + map.forEachIndexed { rowIndex, rowData -> + rowData.forEachIndexed { columnIndex, curInfo -> + if (curInfo == VIRUS) { + spreadVirus( + map, + Position(rowIndex, columnIndex), visit + ) + } + } + } + + return map.sumOf { rowData -> + rowData.count { + it == EMPTY + } + } + } + + private fun spreadVirus(map: MutableList>, startPosition: Position, visit: Array) { + + val queue = ArrayDeque().apply { + add(startPosition) + } + + while (queue.isNotEmpty()) { + + val pos = queue.removeFirst() + + dirs.forEach { dir -> + + val nx = pos.x + dir.x + val ny = pos.y + dir.y + + // 이미 방문한 곳 or 범위 초과시 탐색 X + if (nx !in 0 until map.size || + ny !in 0 until map.first().size || + visit[nx][ny] + ) return@forEach + + if (map[nx][ny] == WALL) return@forEach + + visit[nx][ny] = true + map[nx][ny] = VIRUS + queue.add(Position(nx, ny)) + } + + } + + } + + private fun MutableList>.deepCopy(): MutableList> { + val new = mutableListOf>() + this.forEach { + new.add(it.toMutableList()) + } + return new + } + + companion object { + const val EMPTY = 0 + const val WALL = 1 + const val VIRUS = 2 + const val MAX_INSTALLED_CNT = 3 + } +} + +fun main() { + 전현수_연구소().solution() +} \ No newline at end of file From 5bfe24f7f7b4459348dd5cca32c395b94a652ce5 Mon Sep 17 00:00:00 2001 From: soopeach Date: Fri, 24 Mar 2023 20:14:33 +0900 Subject: [PATCH 2/5] =?UTF-8?q?Feat:=20=EC=B9=9C=EA=B5=AC=EB=B9=84=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\354\271\234\352\265\254\353\271\204.kt" | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 "src/main/kotlin/hyunsoo/28week/\354\271\234\352\265\254\353\271\204.kt" diff --git "a/src/main/kotlin/hyunsoo/28week/\354\271\234\352\265\254\353\271\204.kt" "b/src/main/kotlin/hyunsoo/28week/\354\271\234\352\265\254\353\271\204.kt" new file mode 100644 index 00000000..c0c547c5 --- /dev/null +++ "b/src/main/kotlin/hyunsoo/28week/\354\271\234\352\265\254\353\271\204.kt" @@ -0,0 +1,78 @@ +package hyunsoo.`28week` + +/** + * + * <문제> + * [친구비](https://www.acmicpc.net/problem/16562) + * + * - 아이디어 + * + * - 트러블 슈팅 + * + * 친구 관계가 생기면 무조건 부모의 최소값으로만 비교해서 합집합 연산으로 하도록 하였음. + * - 부모의 비용이 동일하다면 합집합이 안되는 이슈 + * - 동일하다면 부모의 인덱스로 합집합 연산을 하도록 변경 + * + */ +class `전현수_친구비` { + + private lateinit var parent: IntArray + private lateinit var costs: List + + fun solution() { + val (n, m, k) = readln().split(" ").map { it.toInt() } + + parent = IntArray(n + 1) { it } + costs = listOf(0) + readln().split(" ").map { it.toInt() } + val paidInfo = BooleanArray(n + 1) + + repeat(m) { + val (a, b) = readln().split(" ").map { it.toInt() } + union(a, b) + } + + var needCash = 0 + + parent.forEach { + + val parent = getParent(it) + + if (paidInfo[parent].not()) { + needCash += costs[parent] + paidInfo[parent] = true + } + + } + + (k - needCash).apply { + if (this < 0) println("Oh no") + else println(needCash) + } + + } + + private fun getParent(target: Int): Int { + return if (parent[target] == target) target + else getParent(parent[target]) + } + + private fun union(a: Int, b: Int) { + val aParent = getParent(a) + val bParent = getParent(b) + + val aParentCost = costs[aParent] + val bParentCost = costs[bParent] + + if (bParentCost < aParentCost) parent[aParent] = bParent + else if (aParentCost < bParentCost) parent[bParent] = aParent + else { + if (bParent < aParent) parent[aParent] = bParent + else parent[bParent] = aParent + } + } + +} + +fun main() { + 전현수_친구비().solution() +} \ No newline at end of file From a97de8b12fb7843dfbe934e157d55755fba1bae9 Mon Sep 17 00:00:00 2001 From: soopeach Date: Sun, 26 Mar 2023 01:03:34 +0900 Subject: [PATCH 3/5] =?UTF-8?q?Feat:=20=EB=93=9C=EB=9E=98=EA=B3=A4=20?= =?UTF-8?q?=EC=BB=A4=EB=B8=8C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0\352\263\244 \354\273\244\353\270\214.kt" | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 "src/main/kotlin/hyunsoo/28week/\353\223\234\353\236\230\352\263\244 \354\273\244\353\270\214.kt" diff --git "a/src/main/kotlin/hyunsoo/28week/\353\223\234\353\236\230\352\263\244 \354\273\244\353\270\214.kt" "b/src/main/kotlin/hyunsoo/28week/\353\223\234\353\236\230\352\263\244 \354\273\244\353\270\214.kt" new file mode 100644 index 00000000..c0c6d6ea --- /dev/null +++ "b/src/main/kotlin/hyunsoo/28week/\353\223\234\353\236\230\352\263\244 \354\273\244\353\270\214.kt" @@ -0,0 +1,84 @@ +package hyunsoo.`28week` + +/** + * + * <문제> + * [드래곤 커브](https://www.acmicpc.net/problem/15685) + * + * - 아이디어 + * + * - 트러블 슈팅 + * 100도 유효한 좌표였구나... + * + */ +class `전현수_드래곤_커브` { + + private data class Position(val x: Int, val y: Int) { + operator fun plus(other: Position) = Position(this.x + other.x, this.y + other.y) + } + + private val dirs = listOf( + Position(1, 0), + Position(0, -1), + Position(-1, 0), + Position(0, 1), + ) + + private val map = Array(MAP_SIZE) { + IntArray(MAP_SIZE) + } + + fun solution() { + val curveCnt = readln().toInt() + + repeat(curveCnt) { + var (x, y, d, g) = readln().split(" ").map { it.toInt() } + + val moveList = mutableListOf().apply { + add(d) + } + + repeat(g) { + moveList.reversed().forEach { dir -> + val nextDir = (dir + 1).run { + if (this == 4) 0 else this + } + moveList.add(nextDir) + } + } + + map[y][x] = DRAGON_CURVE + + moveList.forEach { dirIndex -> + x += dirs[dirIndex].x + y += dirs[dirIndex].y + map[y][x] = DRAGON_CURVE + } + + } + + var dragonCurveCnt = 0 + + for (i in 0 until MAP_SIZE - 1) { + for (j in 0 until MAP_SIZE - 1) { + if (map[i][j] == DRAGON_CURVE && map[i + 1][j] == DRAGON_CURVE + && map[i][j + 1] == DRAGON_CURVE && map[i + 1][j + 1] == DRAGON_CURVE + ) { + dragonCurveCnt++ + } + } + } + + println(dragonCurveCnt) + + } + + companion object { + const val DRAGON_CURVE = 1 + const val MAP_SIZE = 101 + } +} + +fun main() { + 전현수_드래곤_커브().solution() +} \ No newline at end of file From addcf662c1ad0ce998ca8ff3527859a8bf141aeb Mon Sep 17 00:00:00 2001 From: soopeach Date: Sun, 26 Mar 2023 17:34:12 +0900 Subject: [PATCH 4/5] =?UTF-8?q?Feat:=20=EB=AF=B8=EC=84=B8=EB=A8=BC?= =?UTF-8?q?=EC=A7=80=20=EC=95=88=EB=85=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\354\247\200 \354\225\210\353\205\225!.kt" | 263 ++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 "src/main/kotlin/hyunsoo/28week/\353\257\270\354\204\270\353\250\274\354\247\200 \354\225\210\353\205\225!.kt" diff --git "a/src/main/kotlin/hyunsoo/28week/\353\257\270\354\204\270\353\250\274\354\247\200 \354\225\210\353\205\225!.kt" "b/src/main/kotlin/hyunsoo/28week/\353\257\270\354\204\270\353\250\274\354\247\200 \354\225\210\353\205\225!.kt" new file mode 100644 index 00000000..c1bd6212 --- /dev/null +++ "b/src/main/kotlin/hyunsoo/28week/\353\257\270\354\204\270\353\250\274\354\247\200 \354\225\210\353\205\225!.kt" @@ -0,0 +1,263 @@ +package hyunsoo.`28week` + +/** + * + * <문제> + * [미세먼지 안녕!](https://www.acmicpc.net/problem/17144) + * + * - 아이디어 + * + * - 트러블 슈팅 + * + */ +class `전현수_미세먼지_안녕` { + + private data class Position(var x: Int, var y: Int) { + + fun moveRight() { + this.y++ + } + + fun moveTop() { + this.x-- + } + + fun moveLeft() { + this.y-- + } + + fun moveBottom() { + this.x++ + } + } + + private data class SpreadInfo(val size: Int, val positionList: List) + + private data class MoveDustInfo(val pre: Position, val dir: Position, val size: Int) + + // 상 하 좌 우 + private val dirs = listOf( + Position(-1, 0), + Position(1, 0), + Position(0, -1), + Position(0, 1), + ) + + private val moveInfoList = mutableListOf() + + private val airCleaner = mutableListOf() + + private val room = mutableListOf>() + + fun solution() { + + val (r, c, t) = readln().split(" ").map { it.toInt() } + + repeat(r) { rowIndex -> + val rowData = readln().split(" ").map { it.toInt() }.apply { + this.forEachIndexed { columnIndex, value -> + if (value == AIR_CLEANER) airCleaner.add(Position(rowIndex, columnIndex)) + } + } as MutableList + room.add(rowData) + } + + repeat(t) { + + val SpreadInfos = mutableListOf() + + // 미세먼지 확산정보를 처리 + room.forEachIndexed { rowIndex, rowData -> + rowData.forEachIndexed { columnIndex, value -> + if (value != EMPTY && value != AIR_CLEANER) { + + val spreadList = spread(rowIndex, columnIndex) + val spreadSize = (room[rowIndex][columnIndex] / 5) + + room[rowIndex][columnIndex] -= spreadSize * spreadList.size + + SpreadInfos.add( + SpreadInfo(spreadSize, spreadList) + ) + + } + } + } + + // 미세먼지 확산 정보를 기반으로 확산 작업 진행 + SpreadInfos.forEach { spreadInfo -> + spreadInfo.positionList.forEach { pos -> + room[pos.x][pos.y] += spreadInfo.size + } + } + + airCleaner.forEachIndexed { index, startPosition -> + + moveInfoList.clear() + val curAir = startPosition.apply { + moveRight() + } + + // 우 + blowRight(curAir, index == 0) + + if (index == 0) { + blowTop(curAir) + } else blowBottom(curAir) + + // 좌 + blowLeft(curAir, index == 0) + + // 하 + if (index == 0) { + blowBottom(curAir) + } else { + blowTop(curAir) + } + + moveInfoList.forEach infoLoop@{ info -> + + val pre = info.pre + val dir = info.dir + + // 공기청정기에 들어가면 삭제 + if (room[pre.x + dir.x][pre.y + dir.y] == AIR_CLEANER) return@infoLoop + + room[pre.x + dir.x][pre.y + dir.y] = info.size + } + + } + } + + room.sumOf { rowData -> + rowData + .filter { it != AIR_CLEANER && it != 0 } + .sumOf { it } + }.apply { + println(this) + } + + } + + private fun blowRight(curAir: Position, isFirstAirCleaner: Boolean) { + // 우 + while (curAir.y in 0 until room.first().size) { + + val curInfo = room[curAir.x][curAir.y] + + if (curInfo != EMPTY && curInfo != AIR_CLEANER) { + moveInfoList.add( + // 오른쪽으로 이동 + if (curAir.y != room.first().size - 1) { + MoveDustInfo(curAir.copy(), dirs[3], curInfo) + } else { + // 첫 번째 공기청정기 바람의 마지막은 위로, 아니면 아래로 + if (isFirstAirCleaner) MoveDustInfo(curAir.copy(), dirs[0], curInfo) + else MoveDustInfo(curAir.copy(), dirs[1], curInfo) + } + ) + room[curAir.x][curAir.y] = 0 + } + curAir.moveRight() + } + curAir.moveLeft() + } + + private fun blowTop(curAir: Position) { + while (curAir.x in 0 until room.size) { + + val curInfo = room[curAir.x][curAir.y] + + if (curInfo == AIR_CLEANER) return + + if (curInfo != EMPTY) { + moveInfoList.add( + // 상 이동 + if (curAir.x != 0) { + MoveDustInfo(curAir.copy(), dirs[0], curInfo) + } else MoveDustInfo(curAir.copy(), dirs[2], curInfo) + ) + room[curAir.x][curAir.y] = 0 + } + curAir.moveTop() + } + curAir.moveBottom() + } + + private fun blowLeft(curAir: Position, isFirstAirCleaner: Boolean) { + while (curAir.y in 0 until room.first().size) { + + val curInfo = room[curAir.x][curAir.y] + + if (curInfo != EMPTY && curInfo != AIR_CLEANER) { + moveInfoList.add( + // 좌로 이동 + if (curAir.y != 0) { + MoveDustInfo(curAir.copy(), dirs[2], curInfo) + } else { + // 첫 번째 공기청정기 바람의 마지막은 아래로, 아니면 위로 + if (isFirstAirCleaner) MoveDustInfo(curAir.copy(), dirs[1], curInfo) + else MoveDustInfo(curAir.copy(), dirs[0], curInfo) + } + ) + room[curAir.x][curAir.y] = 0 + } + curAir.moveLeft() + } + curAir.moveRight() + } + + private fun blowBottom(curAir: Position) { + while (curAir.x in 0 until room.size) { + + val curInfo = room[curAir.x][curAir.y] + + if (curInfo == AIR_CLEANER) return + + if (curInfo != EMPTY) { + + moveInfoList.add( + // 하 이동 + if (curAir.x != room.size - 1) { + MoveDustInfo(curAir.copy(), dirs[1], curInfo) + } else MoveDustInfo(curAir.copy(), dirs[2], curInfo) + ) + room[curAir.x][curAir.y] = 0 + } + curAir.moveBottom() + } + curAir.moveTop() + } + + + private fun spread(r: Int, c: Int): List { + + val spreadDusts = mutableListOf() + + dirs.forEach { dir -> + + val nx = r + dir.x + val ny = c + dir.y + + // 범위 초과 혹은 공기 청정기일경우 확신 X + if (nx !in 0 until room.size || + ny !in 0 until room.first().size || + room[nx][ny] == AIR_CLEANER + ) return@forEach + + spreadDusts.add(Position(nx, ny)) + } + + return spreadDusts + + } + + companion object { + private const val AIR_CLEANER = -1 + private const val EMPTY = 0 + } +} + +fun main() { + 전현수_미세먼지_안녕().solution() +} \ No newline at end of file From 071a8908595f8ade4f78c6772c443c05838f042e Mon Sep 17 00:00:00 2001 From: soopeach Date: Sun, 26 Mar 2023 19:49:47 +0900 Subject: [PATCH 5/5] =?UTF-8?q?Rename:=20=EB=AF=B8=EC=84=B8=EB=A8=BC?= =?UTF-8?q?=EC=A7=80=20=EC=95=88=EB=85=95=20=EB=B3=80=EC=88=98=EB=AA=85=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...70\353\250\274\354\247\200 \354\225\210\353\205\225!.kt" | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git "a/src/main/kotlin/hyunsoo/28week/\353\257\270\354\204\270\353\250\274\354\247\200 \354\225\210\353\205\225!.kt" "b/src/main/kotlin/hyunsoo/28week/\353\257\270\354\204\270\353\250\274\354\247\200 \354\225\210\353\205\225!.kt" index c1bd6212..ce869de4 100644 --- "a/src/main/kotlin/hyunsoo/28week/\353\257\270\354\204\270\353\250\274\354\247\200 \354\225\210\353\205\225!.kt" +++ "b/src/main/kotlin/hyunsoo/28week/\353\257\270\354\204\270\353\250\274\354\247\200 \354\225\210\353\205\225!.kt" @@ -64,7 +64,7 @@ class `전현수_미세먼지_안녕` { repeat(t) { - val SpreadInfos = mutableListOf() + val spreadInfoList = mutableListOf() // 미세먼지 확산정보를 처리 room.forEachIndexed { rowIndex, rowData -> @@ -76,7 +76,7 @@ class `전현수_미세먼지_안녕` { room[rowIndex][columnIndex] -= spreadSize * spreadList.size - SpreadInfos.add( + spreadInfoList.add( SpreadInfo(spreadSize, spreadList) ) @@ -85,7 +85,7 @@ class `전현수_미세먼지_안녕` { } // 미세먼지 확산 정보를 기반으로 확산 작업 진행 - SpreadInfos.forEach { spreadInfo -> + spreadInfoList.forEach { spreadInfo -> spreadInfo.positionList.forEach { pos -> room[pos.x][pos.y] += spreadInfo.size }