문제

다솜이는 0과 1로만 이루어진 문자열 S를 가지고 있다. 다솜이는 이 문자열 S에 있는 모든 숫자를 전부 같게 만들려고 한다. 다솜이가 할 수 있는 행동은 S에서 연속된 하나 이상의 숫자를 잡고 모두 뒤집는 것이다. 뒤집는 것은 1을 0으로, 0을 1로 바꾸는 것을 의미한다.

예를 들어 S=0001100 일 때,

  1. 전체를 뒤집으면 1110011이 된다.
  2. 4번째 문자부터 5번째 문자까지 뒤집으면 1111111이 되어서 2번 만에 모두 같은 숫자로 만들 수 있다.

하지만, 처음부터 4번째 문자부터 5번째 문자까지 문자를 뒤집으면 한 번에 0000000이 되어서 1번 만에 모두 같은 숫자로 만들 수 있다.

문자열 S가 주어졌을 때, 다솜이가 해야하는 행동의 최소 횟수를 출력하시오.

입력

첫째 줄에 문자열 S가 주어진다. S의 길이는 100만보다 작다.

출력

첫째 줄에 다솜이가 해야하는 행동의 최소 횟수를 출력한다.

내가 푼 풀이

- 문제의 분류는 그리디였지만 조금 편한방법으로 풀었다.

- 연속된 하나 이상의 숫자를 뒤집을 수 있다.

- 주어진 문자열 S에서 0사이에 있는 1들의 갯수와 1사이에 있는 0들의 갯수를 구해서 둘중 최소값이 행동의 최소횟수가 된다.

 

    • 0001100 -> ["000", "00"] , ["11"]  : 0을 1로 뒤집으면 2번 , 1을 0으로 뒤집으면 1번 뒤집게되므로 최소횟수: 1
    • 11001100110011000001 -> ["00", "00", "00", "00000"] , ["11", "11", "11", "11", "1"] :
    • 0을 1로 뒤집을때 4번, 1을 0으로 뒤집을때 5번이므로, 최소횟수: 4번
import Foundation

var input = readLine()!
var zero = input.split(separator: "0").count
var one = input.split(separator: "1").count
print(min(zero, one))

'코딩테스트 > 백준' 카테고리의 다른 글

BOJ-1202 보석 도둑 Swift  (1) 2023.05.16
BOJ-1339 단어수학 Swift  (0) 2023.05.15
BOJ-16953 A -> B Swift  (0) 2023.05.08
BOJ-1946 신입 사원 Swift  (0) 2023.05.07
BOJ-1715 카드 정렬하기 Swift  (0) 2023.05.06

문제

정수 A를 B로 바꾸려고 한다. 가능한 연산은 다음과 같은 두 가지이다.

  • 2를 곱한다.
  • 1을 수의 가장 오른쪽에 추가한다. 

A를 B로 바꾸는데 필요한 연산의 최솟값을 구해보자.

입력

첫째 줄에 A, B (1 ≤ A < B ≤ 10^9)가 주어진다.

출력

A를 B로 바꾸는데 필요한 연산의 최솟값에 1을 더한 값을 출력한다. 만들 수 없는 경우에는 -1을 출력한다.

내가 푼 풀이

- B를 역순으로 가능한 두가지의 역연산을 한다.

- B의 최댓값이 10^9이므로 UInt64에 담아서 연산한다.

- A에서 두가지연산을 했을때 결과값이 중복이 될 수 없다.

- 2의 배수의 끝자리는 1이 될 수 없고, 뒷자리가 1이면 2의배수가 아니기때문이다.

 

import Foundation

let input = readLine()!.split(separator: " ").map{ UInt64($0)! }
var a = UInt64(input[0])
var b = UInt64(input[1])
var result = 1

while b != a {
    
    if b < a {
        result = -1
        break
    }
    if b % 2 == 0 {
        b /= 2
    } else if b % 10 == 1 {
        b /= 10
    } else {
        result = -1
        break
    }
    result += 1
}
print(result)

 

'코딩테스트 > 백준' 카테고리의 다른 글

BOJ-1339 단어수학 Swift  (0) 2023.05.15
BOJ-1439 뒤집기 Swift  (0) 2023.05.08
BOJ-1946 신입 사원 Swift  (0) 2023.05.07
BOJ-1715 카드 정렬하기 Swift  (0) 2023.05.06
BOJ-10610 30 Swift  (0) 2023.05.05

문제

언제나 최고만을 지향하는 굴지의 대기업 진영 주식회사가 신규 사원 채용을 실시한다. 인재 선발 시험은 1차 서류심사와 2차 면접시험으로 이루어진다. 최고만을 지향한다는 기업의 이념에 따라 그들은 최고의 인재들만을 사원으로 선발하고 싶어 한다.

그래서 진영 주식회사는, 다른 모든 지원자와 비교했을 때 서류심사 성적과 면접시험 성적 중 적어도 하나가 다른 지원자보다 떨어지지 않는 자만 선발한다는 원칙을 세웠다. 즉, 어떤 지원자 A의 성적이 다른 어떤 지원자 B의 성적에 비해 서류 심사 결과와 면접 성적이 모두 떨어진다면 A는 결코 선발되지 않는다.

이러한 조건을 만족시키면서, 진영 주식회사가 이번 신규 사원 채용에서 선발할 수 있는 신입사원의 최대 인원수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에는 테스트 케이스의 개수 T(1 ≤ T ≤ 20)가 주어진다. 각 테스트 케이스의 첫째 줄에 지원자의 숫자 N(1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개 줄에는 각각의 지원자의 서류심사 성적, 면접 성적의 순위가 공백을 사이에 두고 한 줄에 주어진다. 두 성적 순위는 모두 1위부터 N위까지 동석차 없이 결정된다고 가정한다.

출력

각 테스트 케이스에 대해서 진영 주식회사가 선발할 수 있는 신입사원의 최대 인원수를 한 줄에 하나씩 출력한다.

내가 푼 풀이

- 서류시험과 면접시험 둘 중 하나가 다른 지원자보다 높다면 그 지원자를 선발한다.

- 지원자의 숫자만큼 배열을 선언해서 인덱스는 서류심사의성적, 값은 면접성적의 순위를 넣는다.

- 배열의 첫번째 인덱스는 서류심사 1위인 지원자이므로 무조건 선발된다.

- 인덱스의 값이 올라간다는 것은, 서류심사의 순위가 낮아진다는 뜻이다.

- 배열을 순회하며 arr[i] 가 arr[i-1]보다 낮은번호라면( 순위가 더 높다면) i번째 지원자는 i-1번째 지원자보다 서류순위는 낮지만, 면접순위가 높다 -> 선발된다.

- 선발된다면, 기준이 되었던 면접순위는 arr[i] 가 되고, arr[i+1]은 arr[i]와 비교한다. (같은 순위는 없다는 점을 이용함)

- 이 문제는 O(N)도 시간초과가 뜨는것같다.. 그래서 readLine()이였던 느린 입출력을 fileIO()로 바꾸니 시간초과가 뜨지않았다.

 

import Foundation

final class FileIO {
    private var buffer:[UInt8]
    private var index: Int
    
    init(fileHandle: FileHandle = FileHandle.standardInput) {
        buffer = Array(fileHandle.readDataToEndOfFile())+[UInt8(0)]
        index = 0
    }
    
    @inline(__always) private func read() -> UInt8 {
        defer { index += 1 }
        
        return buffer.withUnsafeBufferPointer { $0[index] }
    }
    
    @inline(__always) func readInt() -> Int {
        var sum = 0
        var now = read()
        var isPositive = true
        
        while now == 10
                || now == 32 { now = read() }
        if now == 45{ isPositive.toggle(); now = read() }
        while now >= 48, now <= 57 {
            sum = sum * 10 + Int(now-48)
            now = read()
        }
        
        return sum * (isPositive ? 1:-1)
    }
    
    @inline(__always) func readString() -> String {
        var str = ""
        var now = read()
        
        while now == 10
                || now == 32 { now = read() }
        
        while now != 10
                && now != 32 && now != 0 {
            str += String(bytes: [now], encoding: .ascii)!
            now = read()
        }
        
        return str
    }
}

let file = FileIO()
var count = file.readInt()

for i in 0..<count {
    let num = file.readInt()
    var arr = Array(repeating: 0, count: num+1)
    var result = 1
    for j in 1...num {
        arr[file.readInt()] = file.readInt()
        
    }
    var compare = arr[1]
    
    for i in 2..<arr.count {
        if arr[i] < compare {
            result += 1
            compare = arr[i]
        }
    }
    print(result)
}

 

 

'코딩테스트 > 백준' 카테고리의 다른 글

BOJ-1439 뒤집기 Swift  (0) 2023.05.08
BOJ-16953 A -> B Swift  (0) 2023.05.08
BOJ-1715 카드 정렬하기 Swift  (0) 2023.05.06
BOJ-10610 30 Swift  (0) 2023.05.05
BOJ-13305 주유소 Swift  (0) 2023.05.05

문제

정렬된 두 묶음의 숫자 카드가 있다고 하자. 각 묶음의 카드의 수를 A, B라 하면 보통 두 묶음을 합쳐서 하나로 만드는 데에는 A+B 번의 비교를 해야 한다. 이를테면, 20장의 숫자 카드 묶음과 30장의 숫자 카드 묶음을 합치려면 50번의 비교가 필요하다.

매우 많은 숫자 카드 묶음이 책상 위에 놓여 있다. 이들을 두 묶음씩 골라 서로 합쳐나간다면, 고르는 순서에 따라서 비교 횟수가 매우 달라진다. 예를 들어 10장, 20장, 40장의 묶음이 있다면 10장과 20장을 합친 뒤, 합친 30장 묶음과 40장을 합친다면 (10 + 20) + (30 + 40) = 100번의 비교가 필요하다. 그러나 10장과 40장을 합친 뒤, 합친 50장 묶음과 20장을 합친다면 (10 + 40) + (50 + 20) = 120 번의 비교가 필요하므로 덜 효율적인 방법이다.

N개의 숫자 카드 묶음의 각각의 크기가 주어질 때, 최소한 몇 번의 비교가 필요한지를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 N이 주어진다. (1 ≤ N ≤ 100,000) 이어서 N개의 줄에 걸쳐 숫자 카드 묶음의 각각의 크기가 주어진다. 숫자 카드 묶음의 크기는 1,000보다 작거나 같은 양의 정수이다.

출력

첫째 줄에 최소 비교 횟수를 출력한다.

내가 푼 풀이

- 묶음의 숫자카드들을 저장해둔 배열 A 에서 가장 작은 두 묶음끼리 비교를 하면된다.

- 매번 비교를 할때 배열 A중에서 가장 작은 두개의 카드 묶음을 이용해야하므로 비교할 때 마다 배열이 정렬되어야한다.

- N개의 카드묶음이 있다면 비교횟수는 N-1번이 된다.

1. 배열을 오름차순으로 정렬한다.

2. 배열의 가장 앞자리 두개의 카드묶음을 비교한다.

3. 비교한값을 배열에 다시넣는다.

- 위 1-3 를 반복하면 결과를 얻을 수 있지만, N의 최댓값이 100,000으로 O(N^2)이상은 시간초과가 떴다.

- 최댓값과 최솟값을 빠르게 얻을 수 있는 우선순위 큐를 이용한다.

- 이 문제는 그리디보다 자료구조를 잘 알고 있는지가 더 중요한거같다.

- Swift는 우선순위 큐를 직접 구현해야한다.. 이번기회에 익혀두도록하자.

- 우선순위 큐의 시간복잡도는 O(logN)이다.

 

 

import Foundation

// Heap 구현
struct Heap<T: Comparable> {
    private var elements: [T] = []
    private let sortFunction: (T, T) -> Bool
    
    var isEmpty: Bool {
        return self.elements.count == 1
    }
    
    var peek: T? {
        if self.isEmpty { return nil }
        return self.elements[1]
    }
    
    var count: Int {
        return self.elements.count - 1
    }
    
    init(elements: [T] = [], sortFunction: @escaping (T, T) -> Bool) {
        if !elements.isEmpty {
            self.elements = [elements.first!] + elements
        } else {
            self.elements = elements
        }
        self.sortFunction = sortFunction
        if elements.count > 1 {
            self.buildHeap()
        }
    }
    
    func leftChild(of index: Int) -> Int {
        return index * 2
    }
    func rightChild(of index: Int) -> Int {
        return index * 2 + 1
    }
    func parent(of index: Int) -> Int {
        return index / 2
    }
    
    mutating func swimUp(from index: Int) {
        var index = index
        while index != 1 && self.sortFunction(self.elements[index], self.elements[self.parent(of: index)]) {
            self.elements.swapAt(index, self.parent(of: index))
            index = self.parent(of: index)
        }
    }
    
    mutating func insert(node: T) {
        if self.elements.isEmpty {
            self.elements.append(node)
            return
        }
        self.elements.append(node)
        self.swimUp(from: self.elements.endIndex - 1)
    }
    
    mutating func diveDown(from index: Int) {
        var higherPriority = index
        let leftIndex = self.leftChild(of: index)
        let rightIndex = self.rightChild(of: index)
        
        if leftIndex < self.elements.endIndex && self.sortFunction(self.elements[leftIndex], self.elements[higherPriority]) {
            higherPriority = leftIndex
        }
        
        if rightIndex < self.elements.endIndex && self.sortFunction(self.elements[rightIndex], self.elements[higherPriority]) {
            higherPriority = rightIndex
        }
        
        if higherPriority != index {
            self.elements.swapAt(higherPriority, index)
            self.diveDown(from: higherPriority)
        }
    }
    
    mutating func buildHeap() {
        for index in (1...(self.elements.count / 2)).reversed() {
            self.diveDown(from: index)
        }
    }
    
    mutating func remove() -> T? {
        if self.elements.isEmpty { return nil }
        self.elements.swapAt(1, elements.endIndex - 1)
        let deleted = elements.removeLast()
        self.diveDown(from: 1)
        
        return deleted
    }
    
}


//PriorityQueue 구현
struct PriorityQueue<T: Comparable> {
    var heap: Heap<T>
    
    init(_ elements: [T] = [], _ sort: @escaping (T, T) -> Bool) {
        heap = Heap(elements: elements, sortFunction: sort)
    }
    
    var count: Int {
        return heap.count
    }
    
    var isEmpty: Bool {
        return heap.isEmpty
    }
    
    func top () -> T? {
        return heap.peek
    }
    
    mutating func clear () {
        while !heap.isEmpty {
            heap.remove()
        }
    }
    
    mutating func pop() -> T? {
        return heap.remove()
    }
    
    mutating func push(_ element: T) {
        heap.insert(node: element)
    }
}

let count = Int(String(readLine()!))!
var arr = [Int]()
var result = 0

for i in 0..<count {
    arr.append(Int(String(readLine()!))!)
}

var list = PriorityQueue(arr, { $0 < $1})
for i in 0..<count-1 {
    let num1 = list.pop()!
    let num2 = list.pop()!
    var sum = num1 + num2
    result += sum
    list.push(sum)
}

print(result)

 

자료구조 출처:

https://jeonyeohun.tistory.com/325

 

스위프트로 구현하는 자료구조 5: 힙(Heap)

힙 (Heap) 힙은 이진트리를 사용해서 데이터들을 반정렬 상태로 유지하는 자료구조입니다. 힙은 트리의 루트 노드에 데이터들의 최솟값 혹은 최대값을 저장하는데요, 최솟값을 루트에 둘 때는 최

jeonyeohun.tistory.com

https://jeonyeohun.tistory.com/327

 

스위프트로 구현하는 자료구조 6: 우선순위 큐(Priority Queue)

우선순위 큐(Priority Queue) 우선순위 큐는 힙을 이용해서 가장 높은 우선순위의 있는 요소를 항상 제일 처음에 위치시키는 특별한 큐입니다. 가장 우선순위가 높은 요소가 큐에서 제거되면 그 다

jeonyeohun.tistory.com

 

'코딩테스트 > 백준' 카테고리의 다른 글

BOJ-16953 A -> B Swift  (0) 2023.05.08
BOJ-1946 신입 사원 Swift  (0) 2023.05.07
BOJ-10610 30 Swift  (0) 2023.05.05
BOJ-13305 주유소 Swift  (0) 2023.05.05
BOJ-10162 전자레인지 Swift  (0) 2023.05.05

문제

어느 날, 미르코는 우연히 길거리에서 양수 N을 보았다. 미르코는 30이란 수를 존경하기 때문에, 그는 길거리에서 찾은 수에 포함된 숫자들을 섞어 30의 배수가 되는 가장 큰 수를 만들고 싶어한다.

미르코를 도와 그가 만들고 싶어하는 수를 계산하는 프로그램을 작성하라.

입력

N을 입력받는다. N는 최대 105개의 숫자로 구성되어 있으며, 0으로 시작하지 않는다.

출력

미르코가 만들고 싶어하는 수가 존재한다면 그 수를 출력하라. 그 수가 존재하지 않는다면, -1을 출력하라.

내가 푼 풀이

- 주어진 수의 자리를 바꿔서 30의 배수가 되는 최댓값을 구하면된다.

- 30의 배수면 마지막 자리는 무조건 0이된다.

- 주어진 수를 배열로 변환해서 0을 포함하고, 각자릿수를 더한 값이 3으로 나누어 떨어지면, 그 수는 30의배수가된다.

- 배열을 내림차순으로 바꾼후 위 조건을 따졌을때 30의배수면 그 수를 출력한다.

 

import Foundation


var arr = Array(readLine()!).map{ Int(String($0))! }
arr.sort{$0 > $1}
var sum = arr.reduce(0, +)

if sum % 3 == 0 && arr.contains(0){
    print(arr.map{ String($0)}.joined(separator: ""))
} else {
    print(-1)
}

'코딩테스트 > 백준' 카테고리의 다른 글

BOJ-1946 신입 사원 Swift  (0) 2023.05.07
BOJ-1715 카드 정렬하기 Swift  (0) 2023.05.06
BOJ-13305 주유소 Swift  (0) 2023.05.05
BOJ-10162 전자레인지 Swift  (0) 2023.05.05
BOJ-1789 수들의 합 Swift  (0) 2023.05.04

문제

어떤 나라에 N개의 도시가 있다. 이 도시들은 일직선 도로 위에 있다. 편의상 일직선을 수평 방향으로 두자. 제일 왼쪽의 도시에서 제일 오른쪽의 도시로 자동차를 이용하여 이동하려고 한다. 인접한 두 도시 사이의 도로들은 서로 길이가 다를 수 있다. 도로 길이의 단위는 km를 사용한다.

처음 출발할 때 자동차에는 기름이 없어서 주유소에서 기름을 넣고 출발하여야 한다. 기름통의 크기는 무제한이어서 얼마든지 많은 기름을 넣을 수 있다. 도로를 이용하여 이동할 때 1km마다 1리터의 기름을 사용한다. 각 도시에는 단 하나의 주유소가 있으며, 도시 마다 주유소의 리터당 가격은 다를 수 있다. 가격의 단위는 원을 사용한다.

예를 들어, 이 나라에 다음 그림처럼 4개의 도시가 있다고 하자. 원 안에 있는 숫자는 그 도시에 있는 주유소의 리터당 가격이다. 도로 위에 있는 숫자는 도로의 길이를 표시한 것이다. 

제일 왼쪽 도시에서 6리터의 기름을 넣고, 더 이상의 주유 없이 제일 오른쪽 도시까지 이동하면 총 비용은 30원이다. 만약 제일 왼쪽 도시에서 2리터의 기름을 넣고(2×5 = 10원) 다음 번 도시까지 이동한 후 3리터의 기름을 넣고(3×2 = 6원) 다음 도시에서 1리터의 기름을 넣어(1×4 = 4원) 제일 오른쪽 도시로 이동하면, 총 비용은 20원이다. 또 다른 방법으로 제일 왼쪽 도시에서 2리터의 기름을 넣고(2×5 = 10원) 다음 번 도시까지 이동한 후 4리터의 기름을 넣고(4×2 = 8원) 제일 오른쪽 도시까지 이동하면, 총 비용은 18원이다.

각 도시에 있는 주유소의 기름 가격과, 각 도시를 연결하는 도로의 길이를 입력으로 받아 제일 왼쪽 도시에서 제일 오른쪽 도시로 이동하는 최소의 비용을 계산하는 프로그램을 작성하시오.

입력

표준 입력으로 다음 정보가 주어진다. 첫 번째 줄에는 도시의 개수를 나타내는 정수 N(2 ≤ N ≤ 100,000)이 주어진다. 다음 줄에는 인접한 두 도시를 연결하는 도로의 길이가 제일 왼쪽 도로부터 N-1개의 자연수로 주어진다. 다음 줄에는 주유소의 리터당 가격이 제일 왼쪽 도시부터 순서대로 N개의 자연수로 주어진다. 제일 왼쪽 도시부터 제일 오른쪽 도시까지의 거리는 1이상 1,000,000,000 이하의 자연수이다. 리터당 가격은 1 이상 1,000,000,000 이하의 자연수이다. 

출력

표준 출력으로 제일 왼쪽 도시에서 제일 오른쪽 도시로 가는 최소 비용을 출력한다. 

내가 푼 풀이

- 도시에 도착해야 그 도시의 주유소를 이용할 수 있다.

- 무조건 첫번째 도시에서 주유해야 두번째 도시로 갈 수 있으므로 초기값은 첫번째 도시 가격 X 거리 이다.

- 최대한 적은 비용으로 충전하면서 이동하면 최솟값이 나온다.

- 이전 도시의 기름비용 최솟값을 저장해 두고, 도시에 도착할 때마다 값을 비교한다.

  • 이전 도시보다 가격이 비싼경우 -> 이전 도시들의 기름비용 최솟값 X 그 다음 도시의 거리 를 더해준다.
  • 이전 도시보다 가격이 싼경우 -> 기름비용 최솟값을 갱신해주고, 그 다음 도시의 거리를 곱한 값을 더해준다.
import Foundation

let count = Int(String(readLine()!))!
var distance = readLine()!.split(separator: " ").map{ Int(String($0))! }
var price = readLine()!.split(separator: " ").map{ Int(String($0))! }
var sum = price[0] * distance[0]
var idx = 0
var minPrice = price[0]

if count == 2 {
    print(sum)
} else {
    for i in 1..<distance.count {
        if minPrice > price[i] {
            minPrice = price[i]
        }
        sum = sum + (minPrice * distance[i])
    }
    print(sum)
}

'코딩테스트 > 백준' 카테고리의 다른 글

BOJ-1715 카드 정렬하기 Swift  (0) 2023.05.06
BOJ-10610 30 Swift  (0) 2023.05.05
BOJ-10162 전자레인지 Swift  (0) 2023.05.05
BOJ-1789 수들의 합 Swift  (0) 2023.05.04
BOJ-2217 로프 Swift  (0) 2023.05.04

문제

3개의 시간조절용 버튼 A B C가 달린 전자레인지가 있다. 각 버튼마다 일정한 시간이 지정되어 있어 해당 버튼을 한번 누를 때마다 그 시간이 동작시간에 더해진다. 버튼 A, B, C에 지정된 시간은 각각 5분, 1분, 10초이다.

냉동음식마다 전자레인지로 요리해야할 시간 T가 초단위로 표시되어 있다. 우리는 A, B, C 3개의 버튼을 적절히 눌러서 그 시간의 합이 정확히 T초가 되도록 해야 한다. 단 버튼 A, B, C를 누른 횟수의 합은 항상 최소가 되어야 한다. 이것을 최소버튼 조작이라고 한다.

만일 요리시간이 100초라고 하면(T=100) B를 1번, C는 4번 누르면 된다. 이와 다르게 C를 10번 눌러도 100초가 되지만 이 경우 10번은 최소 횟수가 아니기 때문이 답이 될 수 없다. 이 경우 B 1번, C 4번, 총 5번이 최소버튼 조작이다. 그리고 T=234와 같이 3개의 버튼으로 시간을 정확히 맞출 수 없는 경우도 있다.

여러분은 주어진 요리시간 T초를 맞추기 위한 최소버튼 조작 방법을 구하는 프로그램을 작성해야 한다.

입력

첫 번째 줄에는 요리시간 T(초)가 정수로 주어져 있으며 그 범위는 1 ≤ T ≤ 10,000 이다.

출력

여러분은 T초를 위한 최소버튼 조작의 A B C 횟수를 첫 줄에 차례대로 출력해야 한다. 각각의 횟수 사이에는 빈 칸을 둔다. 해당 버튼을 누르지 않는 경우에는 숫자 0을 출력해야한다. 만일 제시된 3개의 버튼으로 T초를 맞출 수 없으면 음수 -1을 첫 줄에 출력해야 한다.

내가 푼 풀이

- 그리디의 대표문제인 거스름돈과 비슷한 맥락으로 풀면된다.

- 초단위가 더 큰 버튼을 최대한 많이 눌러야 누르는 버튼횟수의 최솟값이 된다.

 

import Foundation

var time = Int(String(readLine()!))!
var arr = [300, 60, 10]
var result = Array(repeating: 0, count: 3)
for i in 0..<arr.count {
    if arr[i] <= time {
        var num = time / arr[i]
        result[i] = num
        time = time - (arr[i] * num)
    }
}
if time != 0 {
    print(-1)
} else {
    print(result.map{String($0)}.joined(separator: " "))
}

'코딩테스트 > 백준' 카테고리의 다른 글

BOJ-10610 30 Swift  (0) 2023.05.05
BOJ-13305 주유소 Swift  (0) 2023.05.05
BOJ-1789 수들의 합 Swift  (0) 2023.05.04
BOJ-2217 로프 Swift  (0) 2023.05.04
BOJ-5585 거스름돈 Swift  (0) 2023.05.04

문제

서로 다른 N개의 자연수의 합이 S라고 한다. S를 알 때, 자연수 N의 최댓값은 얼마일까?

입력

첫째 줄에 자연수 S(1 ≤ S ≤ 4,294,967,295)가 주어진다.

출력

첫째 줄에 자연수 N의 최댓값을 출력한다.

내가 푼 풀이

- 서로다른 N개의 자연수의 합 S 가 주어지는경우 N개가 최댓값이 되기위해선, 낮은 수들끼리의 합이 되어야한다.

- S가 주어진다면 1부터 1씩 증가시키며 S를 차감해준다.

- 증가된 수가 차감된 S보다 커질때의 수가 N의 최댓값이 된다.

S = 10 일때,

  • idx = 1 , S = S - idx = 9
  • idx = 2 , S = S - idx = 7
  • idx = 3 , S = S - idx = 4
  • idx = 4 , S = idx 가되므로 N의 최댓값은 4이다. [1,2,3,4]

idx = 4 라고 서로다른 N개의 자연수가 1,2,3,4 로 된 것은 아니다.

예로 S = 4 일때 

idx = 1, S = S - idx = 3

idx = 2, S = S - idx = 1

S < idx 가 되므로 N의 최댓값은 2 이지만, 서로다른 자연수는 [1,3] 이다.

 

이는 idx를 1씩 증감하고 S에서 빼주는것은

이전 idx가 서로다른 자연수로 들어가 있다고 생각하면된다.

예제 입력 200 의 결과는 19이다.

하지만 1에서 19까지 더한 수는 200이 아닌 190이다.

idx가 1부터 1씩 증가하면서 S를 뺄때, 

idx = 19일때 S에서 idx를 빼면 S = 10

10은 이미 idx가 19까지 올라오면서 거쳤던 자연수이다.

즉 S는 [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,29] 로 N의 최댓값은 19개 , 19가 되는것이다.

따라서 S가 idx 보다 작아질때까지 실행 했을때 idx값이 N의 최댓값이 되는것이다.

import Foundation

var num = Int(String(readLine()!))!
var idx = 0

while num > idx {
    idx += 1
    num -= idx
}

print(idx)

'코딩테스트 > 백준' 카테고리의 다른 글

BOJ-13305 주유소 Swift  (0) 2023.05.05
BOJ-10162 전자레인지 Swift  (0) 2023.05.05
BOJ-2217 로프 Swift  (0) 2023.05.04
BOJ-5585 거스름돈 Swift  (0) 2023.05.04
BOJ-1026 보물 Swift  (0) 2023.05.04

+ Recent posts