Algorithm/Baekjoon

[Swift] 2852 NBA 농구

내일은개발천재🎵 2023. 2. 1. 19:34

문제 사이트

2852번: NBA 농구

 

2852번: NBA 농구

첫째 줄에 골이 들어간 횟수 N(1<=N<=100)이 주어진다. 둘째 줄부터 N개의 줄에 득점 정보가 주어진다. 득점 정보는 득점한 팀의 번호와 득점한 시간으로 이루어져 있다. 팀 번호는 1 또는 2이다. 득

www.acmicpc.net

 

알고리즘

  1. 시간 관련 구조체를 만든다.
  2. n을 입력받는다. (골이 들어간 횟수 → 반복문 실행) 1≤n≤100
  3. 정보를 입력받는다.(n개의 득점 정보)
  4. 골이 들어간 시간과 정보를 기록한다.

코드 설명

1. 시간 관련 Model
    시간을 입력받고, 해당 시간을 편하게 계산하기 위해 연산자 오버로딩을 사용했다.

// 시간 정보를 저장한다.
struct Clock {
    var hour: Int = 0
    var miniute: Int = 0
}

// 시간 계산을 위한 연산자 오버로딩
extension Clock {
    static func -(lhs: Clock, rhs: Clock) -> Clock {
        var miniute = lhs.miniute - rhs.miniute
        var hour = lhs.hour - rhs.hour
        if miniute < 0 {
            miniute += 60
            hour -= 1
        }
        return Clock(hour: hour, miniute: miniute)
    }
    
    static func +(lhs: Clock, rhs: Clock) -> Clock {
        var miniute = lhs.miniute + rhs.miniute
        var hour = lhs.hour + rhs.hour
        if miniute >= 60 {
            miniute -= 60
            hour += 1
        }
        return Clock(hour: hour, miniute: miniute)
    }
    
    static func += (lhs: inout Clock, rhs: Clock) {
        lhs = lhs + rhs
    }
}

 

2. State
    팀 1의 우승 정보이다. (무승부, 이김, 짐)

3. winnerTeam
    팀 1이 골을 넣을 때마다 +1, 팀 2가 골을 넣을 때마다 -1을 한다.
    그렇다면 winnerTeam이 0이라면 동점, 양수라면 이기고 있음을, 음수라면 지고 있음을 의미한다. 

전체 코드

import Foundation

//1. 시간 관련 구조체를 만든다.
struct Clock {
    var hour: Int = 0
    var miniute: Int = 0
}

extension Clock {
    static func -(lhs: Clock, rhs: Clock) -> Clock {
        var miniute = lhs.miniute - rhs.miniute
        var hour = lhs.hour - rhs.hour
        if miniute < 0 {
            miniute += 60
            hour -= 1
        }
        return Clock(hour: hour, miniute: miniute)
    }
    
    static func +(lhs: Clock, rhs: Clock) -> Clock {
        var miniute = lhs.miniute + rhs.miniute
        var hour = lhs.hour + rhs.hour
        if miniute >= 60 {
            miniute -= 60
            hour += 1
        }
        return Clock(hour: hour, miniute: miniute)
    }
    
    static func += (lhs: inout Clock, rhs: Clock) {
        lhs = lhs + rhs
    }
}

enum State {
    case win, draw, lose
}

//2. n을 입력받는다.
let n = Int(readLine()!)!
var prevState = State.draw
//3. 정보를 입력받는다.
var state = State.draw
var winnerTeam = 0 // 0: 무승부, 양수: 1팀 우승, 음수: 2팀 우승
var prevTimeStamp = Clock()
var timeStamp = Clock() {
    didSet {
        let clock = timeStamp - prevTimeStamp
        switch state {
        case .draw:
            if prevState == .lose { result[1] += clock }
            else if prevState == .win { result[0] += clock }
        case .win:
            result[0] += clock
        case .lose:
            result[1] += clock
        }
    }
}
var result = [Clock](repeating: Clock(), count: 2)

//4. 팀의 정보가 바뀔 때마다 이기고 있는 시간을 업데이트한다. (동점인 경우를 고려해야함)
for _ in 0..<n {
    defer {
        prevTimeStamp = timeStamp
        timeStamp = Clock(hour: 48)
    }
    
    let input = readLine()!.split(separator: " ")
    let (team, time) = (input[0], input[1].split(separator: ":").map { Int($0)! })
    winnerTeam = team == "1" ? winnerTeam + 1 : winnerTeam - 1
    prevTimeStamp = timeStamp
    timeStamp = Clock(hour: time[0], miniute: time[1])
    
    switch winnerTeam {
    case 0:
        state = .draw
    case 0...:
        state = .win
    case ...0:
        state = .lose
    default:
        continue
    }
}

result.forEach {
    print(String(format: "%02d:%02d", $0.hour, $0.miniute))
    
}