728x90
https://www.acmicpc.net/problem/1963
1963번: 소수 경로
소수를 유난히도 좋아하는 창영이는 게임 아이디 비밀번호를 4자리 ‘소수’로 정해놓았다. 어느 날 창영이는 친한 친구와 대화를 나누었는데: “이제 슬슬 비번 바꿀 때도 됐잖아” “응 지금
www.acmicpc.net
문제 풀이
1. 주어진 입력을 BFS 를 통해서 완전 탐색 한다.
2. 주어진 숫자는 4자리이므로 천의 자리부터 일의 자리까지 탐색 한다.
3. 0 ~ 9 까지의 숫자를 바꿀 수 있으므로 각 경우에 대해서 탐색한다.
4. 이때 천의 자리가 0으로 올 수 없으므로 조건을 추가 한다.
5. 이전에 탐색한 숫자를 확인하기 위한 방문 배열 visit 를 선언한다.
6. 탐색하는 숫자가 현재 숫자와 같은 지 확인 한다.
7. 변경된 숫자가 소수인지 확인 한다.
8. 목표 숫자에 도착했을 때 변환한 count 값을 출력한다.
코드1 - 에라토스테네스의 체를 몰랐을 때
import java.io.*
import java.util.*
fun main(args: Array<String>) {
val br = BufferedReader(InputStreamReader(System.`in`))
var T = br.readLine().toInt()
val result = StringBuilder()
while (T > 0) {
val (start, target) = br.readLine().split(" ").map { it.toString() }
val count = bfs(start, target)
result.append("${if (count == -1) "Impossible" else count}\n")
T--
}
println(result.toString())
}
private fun bfs(start: String, target: String): Int {
val queue = LinkedList<Prime>()
val visit = BooleanArray(10000) { false }
queue.add(Prime(start, 0))
visit[start.toInt()] = true
while (queue.isNotEmpty()) {
val current = queue.pop()
if (current.number == target) return current.count
for (i in 0..3) {
for (j in 0..9) {
val num = current.number[i] - '0'
val nextNumber = when (i) {
0 -> "$j${current.number.substring(1, current.number.length)}"
1 -> "${current.number.substring(0, 1)}$j${current.number.substring(2, current.number.length)}"
2 -> "${current.number.substring(0, 2)}$j${current.number.substring(3, current.number.length)}"
else -> "${current.number.substring(0, current.number.length - 1)}$j"
}
// 4자리 숫자가 아니다.
if (nextNumber.toInt() / 1000 == 0) continue
// 현재 숫자와 같다.
if (j == num) continue
// 이미 탐색한 숫자.
if (visit[nextNumber.toInt()]) continue
// 소수가 아니다.
if (!isPrime(nextNumber.toInt())) continue
visit[nextNumber.toInt()] = true
queue.add(Prime(nextNumber, current.count + 1))
}
}
}
return -1
}
private fun isPrime(number: Int): Boolean {
for (i in 2 until number) {
if (number % i == 0) return false
}
return true
}
private data class Prime(val number: String, val count: Int)
코드2 - 에라토스테네스의 체 알고리즘 + BFS + StringBuilder.setCharAt
import java.io.*
import java.util.*
fun main(args: Array<String>) {
val br = BufferedReader(InputStreamReader(System.`in`))
var T = br.readLine().toInt()
//에라토스테네스의 체를 이용하여 소수를 구한다.
val prime = BooleanArray(10000) { true }
val sqrt = Math.sqrt(9999.0).toInt()
for (i in 2..sqrt) {
// 소수가 아니다.
if (!prime[i]) continue
//소수인 숫자의 배수를 탐색하여 primeCheck 에서 제거한다.
var j = 2
while (i * j <= 9999) {
if (prime[i * j]) prime[i * j] = false
j++
}
}
val result = StringBuilder()
while (T > 0) {
val (start, target) = br.readLine().split(" ").map { it.toInt() }
val count = bfs(start, target, prime)
result.append("${if (count == -1) "Impossible" else count}\n")
T--
}
println(result.toString())
}
private fun bfs(start: Int, target: Int, prime: BooleanArray): Int {
val queue = LinkedList<Pair<Int, Int>>()
queue.add(Pair(start, 0))
val visit = BooleanArray(10000) { false }
visit[start] = true
while (queue.isNotEmpty()) {
val current = queue.pop()
if (current.first == target) return current.second
for (i in 0..3) {
for (j in 0..9) {
// 천의 자리 숫자는 0으로 될 수 없다.
if (i == 0 && j == 0) continue
// 숫자 변경
val newNumber = getNumber(current.first, i, j)
//소수인지 확인
if (!prime[newNumber]) continue
//이미 탐색한 숫자인 지 확인
if (visit[newNumber]) continue
visit[newNumber] = true
queue.add(Pair(newNumber, current.second + 1))
}
}
}
return -1
}
private fun getNumber(num: Int, index: Int, target: Int): Int {
val sb = StringBuilder()
sb.append(num.toString())
sb.setCharAt(index, target.digitToChar())
return sb.toString().toInt()
}
728x90
'알고리즘(w.KOTLIN) > 그래프(bfs, dfs, 다익스트라)' 카테고리의 다른 글
[백준][코틀린][14395] 4연산 (0) | 2023.04.14 |
---|---|
[백준][코틀린][10026] 적록색약 (0) | 2023.04.13 |
[백준][코틀린][6087] 레이저 통신 (1) | 2023.04.11 |
[백준][16236] 아기 상어 (0) | 2023.04.10 |
[백준][코틀린][16954] 움직이는 미로 탈출 (0) | 2023.03.31 |