본문 바로가기
알고리즘/문제풀이

[백준](Swift) 1차원 배열

by venniek 2022. 6. 4.

1차원 배열 단계를 해결해보자!

10818 최소, 최대

입력 받은 숫자들 중 최솟값, 최댓값을 찾는 문제다.

이 문제를 풀 때는 components를 사용하면 안 된다. 초반 포스팅에서 언급했듯이 입력을 공백 기준으로 자르는 방법으로 components, split 이 두 가지가 있는데 이 중 더 빠른 방법은 split이므로 이 문제는 split을 사용해야만 시간 초과가 나지 않는다. 잘 비교된 글이 있어서 링크를 첨부한다.

Swift split VS components

처음에는 입력을 전부 받고 최솟값을 저장할 minn = 1000000, 최댓값을 저장할 maxn = -1000000을 만들고 입력받은 숫자들을 돌면서 값을 갱신해줬다. 답은 맞았다.

그런데 조금 더 찾아보니 배열에 min(), max() 함수를 사용할 수 있다! 각각 배열 안의 값 중에서 최솟값, 최댓값을 반환한다. 대신 옵셔널이기 때문에 !를 이용해 강제추출 해줘야 한다. 아주 간단하게 코드를 줄일 수 있었다.

// 처음 코드
let n = Int(readLine()!)!
var nums = readLine()!.split(separator: " ").map{ Int($0)! }
var minn:Int = 1000000
var maxn:Int = -1000000
for i in nums {
    minn = min(minn, i)
    maxn = max(maxn, i)
}
print(minn, maxn)
// 줄인 코드
let n = Int(readLine()!)!
var nums = readLine()!.split(separator: " ").map{ Int($0)! }
print(nums.min()!, nums.max()!)

2562 최댓값

9개의 수가 개행으로 나뉘어 주어지면 최댓값이 몇이고 몇 번째에 나오는지 구하면 된다.

값을 저장할 변수와 인덱스를 저장할 변수를 따로 만들어서 숫자 하나씩 입력받으면서 갱신해주면 된다.

var ans = 0
var maxn = 0

for i in 1...9 {
    let n = Int(readLine()!)!
    if n > maxn {
        ans = i
        maxn = n
    }
}
print(maxn)
print(ans)

2577 숫자의 개수

세 자연수를 곱한 결과에 0부터 9까지 각 숫자가 몇 개 쓰이는지 구하는 문제다.

각 숫자가 1000보다 작으므로 세 수를 곱한 값은 Int형에 담을 수 있다. 오버플로우는 걱정하지 않아도 된다.

0부터 9까지 개수를 셀 배열을 만들고 곱해진 값을 10으로 나누면서 1의 자리 수 인덱스를 더해준다.

var n: Int = 1
var cnt = [Int](repeating: 0, count: 10)

for _ in 1...3 {
    n *= Int(readLine()!)!
}
while n > 0 {
    cnt[n % 10] += 1
    n /= 10
}
for c in cnt {
    print(c)
}

3052 나머지

10개 수를 입력받고 각 수를 42로 나눈 나머지를 구해 나머지들 중 서로 다른 값이 몇 개인지 찾는다.

각 수가 몇 개인지는 알 필요가 없기 때문에 위 문제처럼 배열을 만들지 않아도 되고 중복된 값을 걸러주는 Set을 만들어서 넣어주면 서로 다른 값이 몇 개인지 바로 알 수 있다. Set의 원소의 개수는 count로 알 수 있다.

var nums = Set<Int>()

for _ in 1...10 {
    nums.insert(Int(readLine()!)! % 42)
}
print(nums.count)

1546 평균

입력받은 점수들에 특정 연산을 해 새로운 평균을 구하는 문제다.

각 점수를 연산하고 평균을 구하나, 평균을 구하고 연산을 하나 수학적으로 결과는 똑같다. 입력받은 수를 다 더해 개수로 나눠 평균을 구하고, 그 후 최댓값으로 나누고 퍼센트로 바꿔주면 답을 구할 수 있다.

정수형으로 계산하면 오차가 생기기 때문에 합계를 구할 sum과 점수들을 Double로 저장한다. for-in문에서 개수를 범위로 사용하기 때문에 개수 nInt형으로 선언하고, 평균을 구할 때 그냥 나누면 형이 안 맞기 때문에 Double로 형변환을 해준다.

import Foundation
let n = Int(readLine()!)!
var sum: Double = 0.0
let nums = readLine()!.components(separatedBy:" ").map{ Double($0)! }
for i in 0..<n {
    sum += nums[i]
}
print(sum / Double(n) / nums.max()! * 100)

8958 OX퀴즈

n번 문자열이 주어지고 한 문자열 내에 연속된 O의 개수로 점수를 낼 때 최종 점수를 구하는 문제다.

문자열을 돌면서 O가 나오면 현재 점수를 1 더해 최종 합에 더해주고, X가 나오면 현재 점수를 0으로 만든다.

스위프트에서는 문자 하나도 큰따옴표()로 감싼다.

let n = Int(readLine()!)!

for _ in 1...n {
    var now = 0
    var sum = 0
    for c in readLine()! {
        if c == "O" {
            now += 1
            sum += now
        } else {
            now = 0
        }
    }
    print(sum)
}

4344 평균은 넘겠지

케이스가 여러 번 주어지고, 각 케이스마다 평균을 넘는 학생들의 비율을 구한다.

평균을 넘는 학생들이므로 모든 학생의 점수가 같으면 모두 평균과 같은 점수를 가지므로 답은 0%다. 조건문을 초과로 잘 설정해야 한다.

Int형으로 받아 합을 구하고, 평균보다 큰지 검사할 때는 합 < 점수 * 학생 수 을 검사했다. 이렇게 하면 Double형으로 받지 않아도 제대로 비교할 수 있다.

소수점 세 자리까지 출력하는데 사용한 방법은 String format인데 사용법은 다음과 같다.

print(String(format: "%.Nf", value))

// N: 몇 자리까지 남길지
// value: 출력할 값

Int로 받았는데 계산 결과는 실수형이므로 비율을 계산할 때 Double로 형변환 해줘야 한다. 따라서 최종답은 다음과 같다.

import Foundation

let c = Int(readLine()!)!
for _ in 1...c {
    let nums = readLine()!.components(separatedBy: " ").map{ Int($0)! }
    var sum = 0;
    var cnt = 0;
    for i in 1...nums[0] { sum += nums[i] }
    for i in 1...nums[0] {
        if sum < nums[i] * nums[0] { cnt += 1 }
    }
    print(String(format: "%.3f", Double(cnt) / Double(nums[0]) * 100), "%", separator: "")
}

단계가 올라가면서 코드가 점점 길어진다… 이제 한 문제씩 풀이해야겠다ㅠㅠ

'알고리즘 > 문제풀이' 카테고리의 다른 글

[LeetCode] (Swift) 13. Roman to Integer  (0) 2022.09.14
[백준] (Swift) 2675 문자열 반복  (0) 2022.07.11
[백준](Swift) 반복문  (0) 2022.05.28
[백준](Swift) 조건문  (0) 2022.05.13
[백준](Swift) 입출력과 사칙연산  (2) 2022.05.10

댓글