-
Notifications
You must be signed in to change notification settings - Fork 0
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
[Week4] 전현수: 근손실, 톱니바퀴, 트리의 부모 찾기, 회의실 배정, 지름길 #18
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package `4week`.hyunsoo | ||
|
||
class 전현수_근손실{ | ||
/** | ||
* <문제> | ||
* [근손실](https://www.acmicpc.net/problem/18429) | ||
* | ||
* 하루가 지나면 중량이 K만큼 감소 | ||
* N개의 서로 다른 운동 키트를 가지고 있음. | ||
* 하루에 1개씩 키트를 사용. 사용하면 중량이 즉시 증가 | ||
* 운동 키트를 사용하면서 항상 중량이 500이상이 되도록 해야함. | ||
* | ||
* 아이디어 | ||
* - 완탐해서 모든 조합을 구하고 | ||
* - 각 조합들로 운동할 경우 500이상이 되는지를 판정하자! | ||
* | ||
*/ | ||
|
||
val exerciseKitList = mutableListOf<Int>() | ||
var possibleCaseCnt = 0 | ||
val exerciseCase = mutableListOf<Int>() | ||
val visited = BooleanArray(8) { false } | ||
|
||
fun solution() { | ||
|
||
val (exerciseCnt, downWeight) = readln().split(" ").map { it.toInt() } | ||
val exerciseData = readln().split(" ").map { it.toInt() } | ||
exerciseKitList.addAll(exerciseData) | ||
|
||
checkAllCases(0, exerciseCnt, downWeight) | ||
|
||
println(possibleCaseCnt) | ||
} | ||
|
||
fun checkAllCases(cnt: Int, depth: Int, downWeight: Int) { | ||
|
||
if (cnt == depth) { | ||
|
||
var curWeight = 500 | ||
exerciseCase.forEach { upWeight -> | ||
curWeight += upWeight - downWeight | ||
if (curWeight < 500) return | ||
} | ||
possibleCaseCnt++ | ||
return | ||
} | ||
for (index in 0 until exerciseKitList.size) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이부분 |
||
if (visited[index]) continue | ||
|
||
visited[index] = true | ||
exerciseCase.add(exerciseKitList[index]) | ||
checkAllCases(cnt + 1, depth, downWeight) | ||
visited[index] = false | ||
exerciseCase.removeAt(exerciseCase.lastIndex) | ||
} | ||
} | ||
} | ||
|
||
fun main(){ | ||
val myClass = 전현수_근손실() | ||
myClass.solution() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package `4week`.hyunsoo | ||
|
||
import java.lang.Math.min | ||
|
||
/** | ||
* <문제> | ||
* [지름길](https://www.acmicpc.net/problem/1446) | ||
* | ||
* 매일 아침, 세준이는 학교에 가기 위해 차를 타고 D 킬로미터 길이의 고속도로를 지남 | ||
* 어느 날 지름길이 존재하는 것을 알게 되었고, 지름길은 일방통행임 | ||
* 세준이가 운전해야 하는 거리의 최솟값을 구해라 | ||
* | ||
* 입/출력 | ||
* - 첫째 줄 | ||
* - 지름길의 개수 N(12 이하), 고속도로의 길이 D(10,000 이하) | ||
* - N개의 줄 | ||
* - 지름길의 시작 위치, 도착 위치, 지름길의 길이가 주어짐.(10,000 이하) | ||
* | ||
*/ | ||
|
||
class 전현수_지름길{ | ||
|
||
data class ShortCutData(val start: Int, val distance: Int) | ||
|
||
fun solution() { | ||
|
||
val (shortCutCnt, highWayLength) = readln().split(" ").map { it.toInt() } | ||
val dp = Array(10001) { i -> i } | ||
val shortCutGraph = Array(10001) { | ||
mutableListOf<ShortCutData>() | ||
} | ||
|
||
repeat(shortCutCnt) { | ||
val (start, end, shortCutDistance) = readln().split(" ").map { it.toInt() } | ||
// 도착지점이 고속도로의 길이를 넘거나 지름길이 도로보다 길지 않은 경우에만 지름길 생성 | ||
if ((end > highWayLength).not() && | ||
(end - start <= shortCutDistance).not() | ||
) shortCutGraph[end].add(ShortCutData(start, shortCutDistance)) | ||
|
||
} | ||
Comment on lines
+29
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이부분 코틀린의 groupBy를 활용해보면 쓸데없는 데이터는 안 만들 수 있지 않을까요? val shortCutGraph: Map<Int, List<ShortCutData>> = (0 until shortCutCnt).mapNotNull {
val (start, end, shortCutDistance) = readln().split(" ").map { it.toInt() }
if (end <= highWayLength && (end - start) > shortCutDistance) {
end to ShortCutData(start, shortCutDistance)
} else null
}.groupBy({ it.first }, { it.second }) |
||
|
||
for (end in 1..highWayLength) { | ||
dp[end] = dp[end - 1] + 1 | ||
if (shortCutGraph[end].isNotEmpty()) { | ||
shortCutGraph[end].forEach { shortCutData -> | ||
dp[end] = min(dp[end], dp[shortCutData.start] + shortCutData.distance) | ||
} | ||
} | ||
} | ||
Comment on lines
+42
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이부분도 minOf를 써서 잘 활용해서 (1..highWayLength).forEach { end ->
dp[end] = dp[end - 1] + 1
dp[end] = shortCutGraph[end]?.minOf {
dp[it.start] + it.distance
}?.takeIf { it < dp[end] } ?: dp[end]
} minOf 한 값이 dp[end] 보다 작으면 진짜 최솟값인거고 아니면 null 리턴해서 dp[end]를 리턴하는거에요! |
||
|
||
println(dp[highWayLength]) | ||
} | ||
|
||
} | ||
|
||
fun main(){ | ||
val myClass = 전현수_지름길() | ||
myClass.solution() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
package `4week`.hyunsoo | ||
|
||
/** | ||
* <문제> | ||
* [톱니바퀴](https://www.acmicpc.net/problem/14891) | ||
* | ||
* 톱니바퀴는 8개의 톱니를 가지고 있고, 4개가 주어짐 | ||
* - 회전에 대한 정보가 주어지면 | ||
* - 1 ~ 4번의 톱니 상태를 모두 확인하기 | ||
* - 지정된 톱니부터 하나씩 차례로 회전 시키기 | ||
* | ||
* | ||
* | ||
* | ||
* 입/출력 | ||
* - 1 ~ 4째 줄에 톱니바퀴의 상태가 주어짐 | ||
* - 상태는 8개의 정수로 주어지고 12시방향부터 시계방향임. | ||
* - N극은 0, S극은 1 | ||
* - 5째 줄에는 회전 횟수가 주어짐. | ||
* - 그 후 K개의 줄에는 회전시킨 방법이 주어짐. | ||
* - 첫 번째 정수는 회전시킨 톱니바퀴의 번호, 두 번째 정수는 방향 | ||
* - 방향이 1이면 시계 방향, -1이면 반시계 방향 | ||
*/ | ||
|
||
class `전현수_톱니바퀴`{ | ||
data class RotateInfo(val gearNum: Int, val dir: Int) | ||
|
||
class Gear(stateData: String) { | ||
|
||
private val state = IntArray(8) | ||
|
||
init { | ||
stateData.forEachIndexed { index, charNum -> | ||
state[index] = charNum.digitToInt() | ||
} | ||
} | ||
Comment on lines
+28
to
+36
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. class Gear(val state: IntArray) {
constructor(str: String): this(str.map { it.digitToInt() }.toIntArray()) |
||
|
||
// 시계 방향으로 회전 | ||
private fun rotateClockWise() { | ||
val tempState = state.copyOf(state.size) | ||
state[0] = state[state.lastIndex] | ||
tempState.dropLast(1).forEachIndexed { index, num -> | ||
state[index + 1] = num | ||
} | ||
} | ||
|
||
// 반시계 방향으로 회전 | ||
private fun rotateCounterClockWise() { | ||
val tempState = state.copyOf(state.size) | ||
state[state.lastIndex] = state[0] | ||
tempState.drop(1).forEachIndexed { index, num -> | ||
state[index] = num | ||
} | ||
} | ||
|
||
fun rotate(dir: Int) { | ||
if (dir == 1) rotateClockWise() | ||
else rotateCounterClockWise() | ||
} | ||
|
||
private fun getLeftPole() = state[6] | ||
|
||
private fun getRightPole() = state[2] | ||
|
||
fun getPole() = listOf( | ||
getLeftPole(), | ||
getRightPole() | ||
) | ||
|
||
fun getTopState() = state.first() | ||
|
||
override fun toString(): String { | ||
return this.state.joinToString("") | ||
} | ||
} | ||
|
||
|
||
val gearList = Array(4) { | ||
Gear(readln()) | ||
} | ||
|
||
val affectedInfo = Array(4) { | ||
mutableListOf<Int>() | ||
} | ||
|
||
fun solution() { | ||
|
||
val gear1 = gearList.first() | ||
val gear2 = gearList.second() | ||
val gear3 = gearList.third() | ||
val gear4 = gearList.fourth() | ||
Comment on lines
+88
to
+91
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @soopeach 이건 어떠세요? val (gear1, gear2, gear3, gear4) = gearList There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거 야무지네요... |
||
|
||
val rotateCnt = readln().toInt() | ||
|
||
val rotateInfoList = Array(rotateCnt) { | ||
val (gearNum, dir) = readln().split(" ").map { it.toInt() } | ||
RotateInfo(gearNum, dir) | ||
} | ||
|
||
rotateInfoList.forEach { rotateInfo -> | ||
|
||
val (gearNum, dir) = rotateInfo | ||
|
||
val (firstLeft, firstRight) = gear1.getPole() | ||
val (secondLeft, secondRight) = gear2.getPole() | ||
val (thirdLeft, thirdRight) = gear3.getPole() | ||
val (fourthLeft, fourthRight) = gear4.getPole() | ||
|
||
// 회전에 영향을 받을 기어 판정 | ||
if (firstRight != secondLeft) { | ||
affectedInfo[0].add(1) | ||
affectedInfo[1].add(0) | ||
} | ||
if (secondRight != thirdLeft) { | ||
affectedInfo[1].add(2) | ||
affectedInfo[2].add(1) | ||
} | ||
if (thirdRight != fourthLeft) { | ||
affectedInfo[2].add(3) | ||
affectedInfo[3].add(2) | ||
} | ||
Comment on lines
+78
to
+121
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. val gearList = Array(4) {
Gear(readln())
}.toList()
val affectedInfo = Array(4) {
mutableListOf<Int>()
}
fun solution() {
val rotateCnt = readln().toInt()
val rotateInfoList = Array(rotateCnt) {
val (gearNum, dir) = readln().split(" ").map { it.toInt() }
RotateInfo(gearNum, dir)
}
rotateInfoList.forEach { rotateInfo ->
val (gearNum, dir) = rotateInfo
gearList.windowed(2, 1).forEachIndexed { index, gears ->
val (prev, next) = gears.map { it.getPole() }
if (prev.second != next.first) {
affectedInfo[index].add(index + 1)
affectedInfo[index + 1].add(index)
}
} 어... 이런거 있을거같은데? 찾아보면 있더라구요!
|
||
|
||
// 지정된 기어 회전 | ||
rotateGear(gearNum - 1, dir) | ||
|
||
affectedInfo.clear() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Array.clear() 만드실거면 그냥 mutableList를 쓰시죠 |
||
} | ||
|
||
var score = 0 | ||
repeat(4) { cnt -> | ||
score += gearList[cnt].getTopState() * twoToPowOfExponent(cnt) | ||
} | ||
Comment on lines
+129
to
+132
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이건 이제 안할때 된거같지만 val score = gearList.mapIndexed { index, gear ->
gear.getTopState() * twoToPowOfExponent(index)
}.sum() 택 1 val score = (0 until 4).sumOf { gearList[it].getTopState() * twoToPowOfExponent(it) } |
||
|
||
println(score) | ||
|
||
} | ||
|
||
fun rotateGear(gearNum: Int, dir: Int) { | ||
val targetGear = gearList[gearNum] | ||
targetGear.rotate(dir) | ||
val changedDir = dir.dirChange() | ||
val relatedGearList = mutableListOf<Int>() | ||
|
||
affectedInfo[gearNum].forEach { relatedGearNum -> | ||
relatedGearList.add(relatedGearNum) | ||
} | ||
Comment on lines
+142
to
+146
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. val relatedGearList = affectedInfo[gearNum].toList() 랑 뭐가 달라요? |
||
|
||
relatedGearList.forEach { relatedGearNum -> | ||
affectedInfo[gearNum].remove(relatedGearNum) | ||
affectedInfo[relatedGearNum].remove(gearNum) | ||
} | ||
|
||
relatedGearList.forEach { | ||
rotateGear(it, changedDir) | ||
} | ||
} | ||
|
||
// 2차원 배열 안의 리스트들을 초기화 | ||
fun <T> Array<MutableList<T>>.clear() { | ||
this.forEach { | ||
it.clear() | ||
} | ||
} | ||
Comment on lines
+159
to
+163
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 한번 사용하는 함수를 만들 필요가 있을까 싶어요 |
||
|
||
// 2의 거듭제곱 | ||
fun twoToPowOfExponent(exponent: Int): Int { | ||
var powered = 1 | ||
if (exponent == 0) return 1 | ||
repeat(exponent) { | ||
powered *= 2 | ||
} | ||
return powered | ||
} | ||
|
||
// 방향 바꿔주기 | ||
fun Int.dirChange() = if (this == -1) 1 else -1 | ||
|
||
fun <T> Array<T>.second(): T = this[1] | ||
fun <T> Array<T>.third(): T = this[2] | ||
fun <T> Array<T>.fourth(): T = this[3] | ||
Comment on lines
+178
to
+180
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @soopeach ???... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gongdongho12 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거 왜 안지우는거에요? Iterator는 그냥 자동으로 destructure 지원되서 사용 안해도 되요! |
||
} | ||
|
||
fun main(){ | ||
val myClass = 전현수_톱니바퀴() | ||
myClass.solution() | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package `4week`.hyunsoo | ||
|
||
import java.util.* | ||
|
||
/** | ||
* <문제> | ||
* [트리의 부모 찾기](https://www.acmicpc.net/problem/11725) | ||
* | ||
* 루트없는 트리가 주어짐. | ||
* 트리의 루트는 1. 각 노드의 부모를 구하라. | ||
*/ | ||
|
||
class 전현수_트리의_부모_찾기{ | ||
|
||
val rootQueue: Queue<Int> = ArrayDeque() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ArrayDeque보다는 LinkedList가 Queue 자료구조에 더 효율적이에요! |
||
val nodeCnt = readln().toInt() | ||
val treeArray = Array(nodeCnt + 1) { mutableListOf<Int>() } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 중첩되지 않고 사실 순서보다는 실제 Collection의 값을 삭제하는 데에 초점을 맞췄게 때문에 |
||
val parentNodeData = IntArray(nodeCnt + 1) | ||
|
||
// 루트는 1 | ||
val initParent = 1 | ||
|
||
fun solution() { | ||
|
||
|
||
repeat(nodeCnt - 1) { | ||
val (a, b) = readln().split(" ").map { it.toInt() } | ||
treeArray[a].add(b) | ||
treeArray[b].add(a) | ||
} | ||
findParentNode() | ||
parentNodeData.drop(2).forEach { | ||
println(it) | ||
} | ||
Comment on lines
+32
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (minor) 중요하진 않지만 성능개선은 큰폭이에요! 나름 반복인지라 println(parentNodeData.drop(2).joinToString("\n")) |
||
|
||
} | ||
|
||
fun findParentNode() { | ||
|
||
rootQueue.add(initParent) | ||
|
||
while (rootQueue.isNotEmpty()) { | ||
val curParent = rootQueue.poll() | ||
// 부모와 연결되어있는 것들 자식으로 판정 | ||
treeArray[curParent].forEach { child -> | ||
parentNodeData[child] = curParent | ||
// 방문 판정 -> 자식 노드에서 부모 노드 제거 | ||
treeArray[child].remove(curParent) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MutableSet이면 더 효율적으로 삭제될 수 있는 이유 |
||
rootQueue.add(child) | ||
} | ||
} | ||
|
||
} | ||
|
||
} | ||
|
||
fun main(){ | ||
val myClass = 전현수_트리의_부모_찾기() | ||
myClass.solution() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이런부분 lateinit 해주세요!!!!!!