문제

N(1 ≤ N ≤ 100,000)개의 로프가 있다. 이 로프를 이용하여 이런 저런 물체를 들어올릴 수 있다. 각각의 로프는 그 굵기나 길이가 다르기 때문에 들 수 있는 물체의 중량이 서로 다를 수도 있다.

하지만 여러 개의 로프를 병렬로 연결하면 각각의 로프에 걸리는 중량을 나눌 수 있다. k개의 로프를 사용하여 중량이 w인 물체를 들어올릴 때, 각각의 로프에는 모두 고르게 w/k 만큼의 중량이 걸리게 된다.

각 로프들에 대한 정보가 주어졌을 때, 이 로프들을 이용하여 들어올릴 수 있는 물체의 최대 중량을 구해내는 프로그램을 작성하시오. 모든 로프를 사용해야 할 필요는 없으며, 임의로 몇 개의 로프를 골라서 사용해도 된다.

입력

첫째 줄에 정수 N이 주어진다. 다음 N개의 줄에는 각 로프가 버틸 수 있는 최대 중량이 주어진다. 이 값은 10,000을 넘지 않는 자연수이다.

출력

첫째 줄에 답을 출력한다.

내가 푼 풀이

- 로프를 모두 사용하지 않아도 된다.

- 주어진 로프를 최대로 들수있는 중량이 큰 순으로 정렬한다.

- 로프가 추가되면, 추가된 로프의 중량값 x 로프의 갯수 = 버틸 수 있는 중량 이된다.

- 갱신한 값 출력

  • [15, 10, 5] 로프 1개일때, 최대중량: [15] ---> 15
  • [15, 10, 5] 로프 2개일때, 최대중량: [15,10] ---> 10 X 2 = 20 (정답)
  • [15, 10, 5] 로프 3개일때, 최대중량: [15,10,5] ---> 5 X 3 = 15 

 

import Foundation

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

for i in 0..<count {
    let num = Int(String(readLine()!))!
    arr.append(num)
}
arr.sort{ $0 > $1}
var max = arr[0]

if arr.count == 1 {
    print(max)
} else {
    for i in 1..<arr.count {
        if max < arr[i] * (i+1) {
            max = arr[i] * (i+1)
        }
    }
    print(max)
}

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

BOJ-10162 전자레인지 Swift  (0) 2023.05.05
BOJ-1789 수들의 합 Swift  (0) 2023.05.04
BOJ-5585 거스름돈 Swift  (0) 2023.05.04
BOJ-1026 보물 Swift  (0) 2023.05.04
BOJ-1541 잃어버린 괄호 Swift  (0) 2023.05.04

문제

타로는 자주 JOI잡화점에서 물건을 산다. JOI잡화점에는 잔돈으로 500엔, 100엔, 50엔, 10엔, 5엔, 1엔이 충분히 있고, 언제나 거스름돈 개수가 가장 적게 잔돈을 준다. 타로가 JOI잡화점에서 물건을 사고 카운터에서 1000엔 지폐를 한장 냈을 때, 받을 잔돈에 포함된 잔돈의 개수를 구하는 프로그램을 작성하시오.

입력

입력은 한줄로 이루어져있고, 타로가 지불할 돈(1 이상 1000미만의 정수) 1개가 쓰여져있다.

출력

제출할 출력 파일은 1행으로만 되어 있다. 잔돈에 포함된 매수를 출력하시오.

내가 푼 풀이

- 그리디의 대표적인문제로, 돈의 크기가 큰순으로 최대한 많이 거슬러주면된다.

 

import Foundation

var money = 1000 - Int(String(readLine()!))!
var arr = [500, 100, 50, 10, 5, 1]
var result = 0

for i in arr {
    if i <= money {
        var num = money / i
        result += num
        money -= i * num
    }
}
print(result)

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

BOJ-1789 수들의 합 Swift  (0) 2023.05.04
BOJ-2217 로프 Swift  (0) 2023.05.04
BOJ-1026 보물 Swift  (0) 2023.05.04
BOJ-1541 잃어버린 괄호 Swift  (0) 2023.05.04
BOJ-11399 ATM Swift  (1) 2023.05.03

문제

옛날 옛적에 수학이 항상 큰 골칫거리였던 나라가 있었다. 이 나라의 국왕 김지민은 다음과 같은 문제를 내고 큰 상금을 걸었다.

길이가 N인 정수 배열 A와 B가 있다. 다음과 같이 함수 S를 정의하자.

S = A[0] × B[0] + ... + A[N-1] × B[N-1]

S의 값을 가장 작게 만들기 위해 A의 수를 재배열하자. 단, B에 있는 수는 재배열하면 안 된다.

S의 최솟값을 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 N이 주어진다. 둘째 줄에는 A에 있는 N개의 수가 순서대로 주어지고, 셋째 줄에는 B에 있는 수가 순서대로 주어진다. N은 50보다 작거나 같은 자연수이고, A와 B의 각 원소는 100보다 작거나 같은 음이 아닌 정수이다.

출력

첫째 줄에 S의 최솟값을 출력한다.

내가 푼 풀이

- 문제에서는 B를 재배열 하면 안된다고 했지만, 구하는 수는 S의 최솟값이다.

- 배열 A를 오름차순, 배열 B를 내림차순으로 정렬하여 서로 곱한값을 모두 합하면 최솟값이다.

 

import Foundation

let count = Int(String(readLine()!))!
var arrA = readLine()!.split(separator: " ").map{ Int(String($0))! }
var arrB = readLine()!.split(separator: " ").map{ Int(String($0))! }
var sum = 0
arrA.sort{ $0 < $1}
arrB.sort{ $0 > $1}

for i in 0..<count{
    sum = sum + (arrA[i] * arrB[i])
}
print(sum)

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

BOJ-2217 로프 Swift  (0) 2023.05.04
BOJ-5585 거스름돈 Swift  (0) 2023.05.04
BOJ-1541 잃어버린 괄호 Swift  (0) 2023.05.04
BOJ-11399 ATM Swift  (1) 2023.05.03
BOJ-9251 LCS Swift  (0) 2023.04.29

문제

세준이는 양수와 +, -, 그리고 괄호를 가지고 식을 만들었다. 그리고 나서 세준이는 괄호를 모두 지웠다.

그리고 나서 세준이는 괄호를 적절히 쳐서 이 식의 값을 최소로 만들려고 한다.

괄호를 적절히 쳐서 이 식의 값을 최소로 만드는 프로그램을 작성하시오.

입력

첫째 줄에 식이 주어진다. 식은 ‘0’~‘9’, ‘+’, 그리고 ‘-’만으로 이루어져 있고, 가장 처음과 마지막 문자는 숫자이다. 그리고 연속해서 두 개 이상의 연산자가 나타나지 않고, 5자리보다 많이 연속되는 숫자는 없다. 수는 0으로 시작할 수 있다. 입력으로 주어지는 식의 길이는 50보다 작거나 같다.

출력

첫째 줄에 정답을 출력한다.

내가 푼 풀이

- 식의 값 최소로 만드는방법은 음수의 값을 최대로 만들면된다.

- 처음숫자는 무조건 양수이다.

- 문자열로 저장해서 음수(-) 가 나온다면, 그 이후로 나오는 모든 숫자는 빼주면 된다.

 

import Foundation

var str = Array(readLine()!).map{String($0)}
var sum = 0
var isSub = false
var numArr = [String]()

for i in str {
    if Int(i) != nil {
        numArr.append(i)
    } else {
        if isSub {
            sum -= Int(numArr.joined(separator: ""))!
            numArr = []
        } else {
            sum += Int(numArr.joined(separator: ""))!
            numArr = []
        }
        
        if i == "-" {
            isSub = true
        }
    }
}

if isSub {
    sum -= Int(numArr.joined(separator: ""))!
} else {
    sum += Int(numArr.joined(separator: ""))!
}

print(sum)

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

BOJ-5585 거스름돈 Swift  (0) 2023.05.04
BOJ-1026 보물 Swift  (0) 2023.05.04
BOJ-11399 ATM Swift  (1) 2023.05.03
BOJ-9251 LCS Swift  (0) 2023.04.29
BOJ-11052 카드 구매하기 Swift  (0) 2023.04.28

문제

인하은행에는 ATM이 1대밖에 없다. 지금 이 ATM앞에 N명의 사람들이 줄을 서있다. 사람은 1번부터 N번까지 번호가 매겨져 있으며, i번 사람이 돈을 인출하는데 걸리는 시간은 Pi분이다.

사람들이 줄을 서는 순서에 따라서, 돈을 인출하는데 필요한 시간의 합이 달라지게 된다. 예를 들어, 총 5명이 있고, P1 = 3, P2 = 1, P3 = 4, P4 = 3, P5 = 2 인 경우를 생각해보자. [1, 2, 3, 4, 5] 순서로 줄을 선다면, 1번 사람은 3분만에 돈을 뽑을 수 있다. 2번 사람은 1번 사람이 돈을 뽑을 때 까지 기다려야 하기 때문에, 3+1 = 4분이 걸리게 된다. 3번 사람은 1번, 2번 사람이 돈을 뽑을 때까지 기다려야 하기 때문에, 총 3+1+4 = 8분이 필요하게 된다. 4번 사람은 3+1+4+3 = 11분, 5번 사람은 3+1+4+3+2 = 13분이 걸리게 된다. 이 경우에 각 사람이 돈을 인출하는데 필요한 시간의 합은 3+4+8+11+13 = 39분이 된다.

줄을 [2, 5, 1, 4, 3] 순서로 줄을 서면, 2번 사람은 1분만에, 5번 사람은 1+2 = 3분, 1번 사람은 1+2+3 = 6분, 4번 사람은 1+2+3+3 = 9분, 3번 사람은 1+2+3+3+4 = 13분이 걸리게 된다. 각 사람이 돈을 인출하는데 필요한 시간의 합은 1+3+6+9+13 = 32분이다. 이 방법보다 더 필요한 시간의 합을 최소로 만들 수는 없다.

줄을 서 있는 사람의 수 N과 각 사람이 돈을 인출하는데 걸리는 시간 Pi가 주어졌을 때, 각 사람이 돈을 인출하는데 필요한 시간의 합의 최솟값을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 사람의 수 N(1 ≤ N ≤ 1,000)이 주어진다. 둘째 줄에는 각 사람이 돈을 인출하는데 걸리는 시간 Pi가 주어진다. (1 ≤ Pi ≤ 1,000)

출력

첫째 줄에 각 사람이 돈을 인출하는데 필요한 시간의 합의 최솟값을 출력한다.

내가 푼 풀이

- 시간이 오래걸리는 사람이 먼저 있으면 다음사람도 그 시간만큼 기다려야한다.

- 적게 걸리는사람의 순서가 앞이면 기다리는 시간의 최솟값이 된다.

 

import Foundation

let count = Int(String(readLine()!))!
var arr = readLine()!.split(separator: " ").map{ Int(String($0))!}
var sortedArr = arr.sorted{ $0 < $1 }
var sum = 0

for i in 0..<sortedArr.count {
    var num = 0
    for j in 0...i {
        num += sortedArr[j]
    }
    sum += num
}

print(sum)

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

BOJ-1026 보물 Swift  (0) 2023.05.04
BOJ-1541 잃어버린 괄호 Swift  (0) 2023.05.04
BOJ-9251 LCS Swift  (0) 2023.04.29
BOJ-11052 카드 구매하기 Swift  (0) 2023.04.28
BOJ-1904 01타일 Swift  (1) 2023.04.27

문제

LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다.

예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다.

입력

첫째 줄과 둘째 줄에 두 문자열이 주어진다. 문자열은 알파벳 대문자로만 이루어져 있으며, 최대 1000글자로 이루어져 있다.

출력

첫째 줄에 입력으로 주어진 두 문자열의 LCS의 길이를 출력한다.

내가 푼 풀이

- dp[i][j] = 길이 i인 문자 s1과 길이 j인 문자 s2 의 가장 긴 수열의 길이라 한다.

- s1, s2 문자열을 순회한다.

  • 문자가 같으면 dp[i-1][j-1] + 1
  • 문자가 다르면 max( dp[i-1][j], dp[i][j-1] )
    A C A Y K P
  0 0 0 0 0 0 0
C 0 0 1 1 1 1 1
A 0 1 1 2 2 2 2
P 0 1 1 2 2 2 3
C 0 1 2 2 2 2 3
A 0 1 2 3 3 3 3
K 0 1 2 3 3 4 4

 

import Foundation

var str1 = readLine()!
var str2 = readLine()!
var strArr1 = ["0"] + str1.map{String($0)}
var strArr2 = ["0"] + str2.map{String($0)}
var dp = Array(repeating: Array(repeating: 0, count: str1.count+1), count: str2.count+1)


for i in 1...str2.count {
    for j in 1...str1.count {
        if strArr2[i] == strArr1[j] {
            dp[i][j] = dp[i-1][j-1] + 1
        } else {
            dp[i][j] = max(dp[i-1][j], dp[i][j-1])
        }
    }
}

print(dp[str2.count][str1.count])

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

BOJ-1541 잃어버린 괄호 Swift  (0) 2023.05.04
BOJ-11399 ATM Swift  (1) 2023.05.03
BOJ-11052 카드 구매하기 Swift  (0) 2023.04.28
BOJ-1904 01타일 Swift  (1) 2023.04.27
BOJ-12865 평범한 배낭 Swift  (1) 2023.04.26

문제

요즘 민규네 동네에서는 스타트링크에서 만든 PS카드를 모으는 것이 유행이다.

PS카드는 PS(Problem Solving)분야에서 유명한 사람들의 아이디와 얼굴이 적혀있는 카드이다. 각각의 카드에는 등급을 나타내는 색이 칠해져 있고, 다음과 같이 8가지가 있다.

  • 설카드
  • 레드카드
  • 오렌지카드
  • 퍼플카드
  • 블루카드
  • 청록카드
  • 그린카드
  • 그레이카드

카드는 카드팩의 형태로만 구매할 수 있고, 카드팩의 종류는 카드 1개가 포함된 카드팩, 카드 2개가 포함된 카드팩, ... 카드 N개가 포함된 카드팩과 같이 총 N가지가 존재한다.

민규는 카드의 개수가 적은 팩이더라도 가격이 비싸면 높은 등급의 카드가 많이 들어있을 것이라는 미신을 믿고 있다. 따라서, 민규는 돈을 최대한 많이 지불해서 카드 N개 구매하려고 한다. 카드가 i개 포함된 카드팩의 가격은 Pi원이다.

예를 들어, 카드팩이 총 4가지 종류가 있고, P1 = 1, P2 = 5, P3 = 6, P4 = 7인 경우에 민규가 카드 4개를 갖기 위해 지불해야 하는 금액의 최댓값은 10원이다. 2개 들어있는 카드팩을 2번 사면 된다.

P1 = 5, P2 = 2, P3 = 8, P4 = 10인 경우에는 카드가 1개 들어있는 카드팩을 4번 사면 20원이고, 이 경우가 민규가 지불해야 하는 금액의 최댓값이다.

마지막으로, P1 = 3, P2 = 5, P3 = 15, P4 = 16인 경우에는 3개 들어있는 카드팩과 1개 들어있는 카드팩을 구매해 18원을 지불하는 것이 최댓값이다.

카드 팩의 가격이 주어졌을 때, N개의 카드를 구매하기 위해 민규가 지불해야 하는 금액의 최댓값을 구하는 프로그램을 작성하시오. N개보다 많은 개수의 카드를 산 다음, 나머지 카드를 버려서 N개를 만드는 것은 불가능하다. 즉, 구매한 카드팩에 포함되어 있는 카드 개수의 합은 N과 같아야 한다.

입력

첫째 줄에 민규가 구매하려고 하는 카드의 개수 N이 주어진다. (1 ≤ N ≤ 1,000)

둘째 줄에는 Pi가 P1부터 PN까지 순서대로 주어진다. (1 ≤ Pi ≤ 10,000)

출력

첫째 줄에 민규가 카드 N개를 갖기 위해 지불해야 하는 금액의 최댓값을 출력한다.

내가 푼 풀이

- N개의 카드를 구매하기 위해 돈을 최대로 지불하는 금액이 얼마인지 구하면 된다.

- P1 부터 PN까지 주어졌을때 이를 인덱스로 정해 N이 되는 중복조합을 구해서 이 중 최댓값을 구하게 했는데 시간초과가 떴다.

- n개의 카드를 구하는 경우의수를 다른 방법으로 구해보자.

- dp[n]: n개의 카드를 구매할때의 비용 최댓값 이라고 지정하자.

- n개의 카드를 구매할때 

  • 1개가 들어있는 P1을 구매하는경우:  P1 + P(n-1)
  • 2개가 들어있는 P2를 구매하는경우: P2 + P(n-2)
  • 3개가 들어있는 P3를 구매하는경우: P3 + P(n-3)
  • N개가 들어있는 PN을 구매하는경우: PN + P(n-n) = PN

이를 이용해서 최댓값을 저장한 dp를 재사용한다.

arr에 P1부터 PN의 비용을 저장한 후

  • 1개가 들어있는 P1을 구매할때 비용의 최댓값: P1 + dp[n-1]
  • 2개가 들어있는 P2을 구매할때 비용의 최댓값: P2 + dp[n-2]
  • 3개가 들어있는 P3을 구매할때 비용의 최댓값: P3 + dp[n-3]
  • N개가 들어있는 PN을 구매할때 비용의 최댓값: PN + dp[n-n] = PN

dp에 값을 저장할때 1부터 n까지 순회하며 최댓값을 갱신하여 저장한다.

 

 

import Foundation

let num = Int(String(readLine()!))!
var dp = Array(repeating: 0, count: num+1)
var arr = readLine()!.split(separator: " ").map{ Int(String($0))! }
arr.insert(0, at: 0)
dp[1] = arr[1]

if num > 1 {
    for i in 2...num {
        var max = 0
        for j in 1...i {
            let price = arr[j] + dp[i-j]
            if price > max {
                max = price
            }
        }
        dp[i] = max
    }
    print(dp[num])
} else {
    print(dp[1])
}

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

BOJ-11399 ATM Swift  (1) 2023.05.03
BOJ-9251 LCS Swift  (0) 2023.04.29
BOJ-1904 01타일 Swift  (1) 2023.04.27
BOJ-12865 평범한 배낭 Swift  (1) 2023.04.26
BOJ-14501 퇴사 Swift  (0) 2023.04.25

문제

지원이에게 2진 수열을 가르쳐 주기 위해, 지원이 아버지는 그에게 타일들을 선물해주셨다. 그리고 이 각각의 타일들은 0 또는 1이 쓰여 있는 낱장의 타일들이다.

어느 날 짓궂은 동주가 지원이의 공부를 방해하기 위해 0이 쓰여진 낱장의 타일들을 붙여서 한 쌍으로 이루어진 00 타일들을 만들었다. 결국 현재 1 하나만으로 이루어진 타일 또는 0타일을 두 개 붙인 한 쌍의 00타일들만이 남게 되었다.

그러므로 지원이는 타일로 더 이상 크기가 N인 모든 2진 수열을 만들 수 없게 되었다. 예를 들어, N=1일 때 1만 만들 수 있고, N=2일 때는 00, 11을 만들 수 있다. (01, 10은 만들 수 없게 되었다.) 또한 N=4일 때는 0011, 0000, 1001, 1100, 1111 등 총 5개의 2진 수열을 만들 수 있다.

우리의 목표는 N이 주어졌을 때 지원이가 만들 수 있는 모든 가짓수를 세는 것이다. 단 타일들은 무한히 많은 것으로 가정하자.

입력

첫 번째 줄에 자연수 N이 주어진다. (1 ≤ N ≤ 1,000,000)

출력

첫 번째 줄에 지원이가 만들 수 있는 길이가 N인 모든 2진 수열의 개수를 15746으로 나눈 나머지를 출력한다.

내가 푼 풀이

- 1 또는 00 타일을 깔 수 있다.

- dp[i]는 i자리의 타일 깔 수 있는 자리수라 한다.

  • i자리 2진수의 첫번째 숫자가 1로 시작한다면, i-1자리 2진수의 가짓수를 최대로 센다.
  • i자리 2진수의 첫번째 숫자가 00으로 시작한다면, i-2자리 2진수의 가짓수를 최대로 센다.

- 위 두가지 경우를 고려해 점화식을 세우면 dp[i] = dp[i-1] + dp[i-2] 가된다.

 

import Foundation

let count = Int(String(readLine()!))!

var dp = Array(repeating: 0, count: 1000001)
dp[1] = 1
dp[2] = 2
for i in 3..<dp.count{
    dp[i] = (dp[i-1] + dp[i-2]) % 15746
}

print(dp[count])

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

BOJ-9251 LCS Swift  (0) 2023.04.29
BOJ-11052 카드 구매하기 Swift  (0) 2023.04.28
BOJ-12865 평범한 배낭 Swift  (1) 2023.04.26
BOJ-14501 퇴사 Swift  (0) 2023.04.25
BOJ-2193 이친수 Swift  (0) 2023.04.25

+ Recent posts