[문제]
https://www.acmicpc.net/problem/17281
17281번: ⚾
⚾는 9명으로 이루어진 두 팀이 공격과 수비를 번갈아 하는 게임이다. 하나의 이닝은 공격과 수비로 이루어져 있고, 총 N이닝 동안 게임을 진행해야 한다. 한 이닝에 3아웃이 발생하면 이닝이 종
www.acmicpc.net
주의 : 코틀린으로 풀 때, 베이스를 배열에 저장해놓고 풀게 되면, 시간초과가 발생합니다.
[풀이]
- 문제 설명
문제를 이해를 잘못해서 한 번 삽질하고, 시간초과 때문에 두 번 고생한 문제이다.
간단하게 요약을 하면,
입력값 N은 이닝 수 이다. 이닝 수는 야구로 생각하면 1회초, 1회말의 그 1회를 의미한다.
입력으로 들어온 이닝 수 만큼 경기를 진행했을 때, 얻을 수 있는 최고점을 기록하는 문제이다.
선수는 총 9명으로 고정되어 있고, 각 선수가 해당 이닝에서 얻을 수 있는 점수를 두번째 열부터 입력으로 주어진다.
- 풀이
DFS를 이용하여 풀었다.
1~9까지 순서로 각 숫자마다 타자를 저장해 놓은 배열 lineUp과
DFS 탐색을 위해 이미 방문한 곳은 방문하지 않아야 하므로, 상태를 저장해놓은 visit 배열을 사용한다.
특히 4번타자는 1번으로 타자 자리에 선다는 조건이 있으므로,
lineUp[3] = 0
visit[3] = true
dfs 함수를 호출하기 전에 다음과 같이 설정해야 한다.
dfs 과정은 다음과 같다.
fun dfs(cnt : Int)
{
if(cnt == 9)
{
cal()
return
}
for(i in 0 until lineUp.size)
{
if(visit[i]) continue
visit[i] = true
lineUp[i] = cnt
dfs(cnt + 1)
visit[i] = false
}
}
cnt의 경우에는 타자이다. cnt가 0인경우 1번타자를 의미한다.
cnt가 9에 도달할 경우 9개의 타자가 모두 lineUp배열에 저장이 되었기 때문에 점수를 계산하는 cal() 함수를 호출한다.
그게 아닐 경우에는
for-구문을 돌면서, 방문한지 체크를 하고, 방문하지 않았을 경우에는 값을 저장해주고, dfs를 다시 호출해준다.
그리고 다시 방문을 초기화해줌으로써 순열을 만들어준다.
- 점수 계산
점수 계산은 처음에 각 1루, 2루,3루를 base라는 이름의 배열에 저장하여 사용했는데 시간 초과가 발생하였다.
1루를 base1, 2루를 base2, 3루를 base3로 따로 지정해주어 제출하였더니 정답처리 되었다.
중요한 점은 아래와 같다.
1. 아웃 카운트가 3이 될 때까지 해당 이닝의 선수 라인업이 계속 반복이 된다
2. 해당 이닝이 끝나면, 끝날 때 선수의 다음에 오는 선수가 다음 이닝에 1번 주자로 나오게 된다.
위를 주의하여 코드를 작성하면 아래와 같다.
fun cal()
{
var tmp = 0
var status = false
var score = 0
repeat(N)
{
i ->
var out = 0
status = false
var base1 = 0
var base2 = 0
var base3 = 0
while(!status)
{
while (tmp < lineUp.size){
val player = baseball[i][lineUp[tmp]]
when(player)
{
0 -> {
out++
}
1 -> {
score += base3
base3 = base2
base2 = base1
base1 = 1
}
2 -> {
score += (base3 + base2)
base3 = base1
base2 = 1
base1 = 0
}
3 -> {
score += (base3 + base2 + base1)
base1 = 0
base2 = 0
base3 = 1
}
4 -> {
score += (base3 + base2 + base1 + 1)
base1 = 0
base2 = 0
base3 = 0
}
}
tmp++
tmp %= 9
if(out == 3) {
out = 0
status = true
break
}
}
}
ans = max(ans , score)
}
}
[전체 코드]
import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter
import kotlin.math.max
var N = 0
var ans = 0
lateinit var baseball : Array<MutableList<Int>>
val lineUp = MutableList<Int>(9){-1}
val visit = MutableList<Boolean>(9){false}
fun main() {
val br = BufferedReader(InputStreamReader(System.`in`))
val bw = BufferedWriter(OutputStreamWriter(System.out))
N = br.readLine().toInt()
baseball = Array(N){ mutableListOf() }
repeat(N)
{
i ->
baseball[i] = br.readLine().split(" ").map { it.toInt()} as MutableList<Int>
}
lineUp[3] = 0
visit[3] = true
dfs(1)
bw.write(ans.toString())
bw.flush()
bw.close()
}
fun dfs(cnt : Int)
{
if(cnt == 9)
{
cal()
return
}
for(i in 0 until lineUp.size)
{
if(visit[i]) continue
visit[i] = true
lineUp[i] = cnt
dfs(cnt + 1)
visit[i] = false
}
}
fun cal()
{
var tmp = 0
var status = false
var score = 0
repeat(N)
{
i ->
var out = 0
status = false
var base1 = 0
var base2 = 0
var base3 = 0
while(!status)
{
while (tmp < lineUp.size){
val player = baseball[i][lineUp[tmp]]
when(player)
{
0 -> {
out++
}
1 -> {
score += base3
base3 = base2
base2 = base1
base1 = 1
}
2 -> {
score += (base3 + base2)
base3 = base1
base2 = 1
base1 = 0
}
3 -> {
score += (base3 + base2 + base1)
base1 = 0
base2 = 0
base3 = 1
}
4 -> {
score += (base3 + base2 + base1 + 1)
base1 = 0
base2 = 0
base3 = 0
}
}
tmp++
tmp %= 9
if(out == 3) {
out = 0
status = true
break
}
}
}
ans = max(ans , score)
}
}
'백준 > bfs dfs' 카테고리의 다른 글
백준 [9466] kotlin (0) | 2023.07.20 |
---|---|
백준 [15991] kotlin (0) | 2023.05.22 |
백준 [4179] kotlin (1) | 2023.01.18 |
백준 [1167] kotlin (0) | 2023.01.16 |
백준 [2638] kotlin (0) | 2023.01.15 |