세 번째 단계인 반복문이다.
2739 구구단
1…9
인 N
을 받아서 N
단을 출력하는 문제다.
9번 반복하고, print
함수가 인수를 자동으로 공백으로 나눠주니 출력할 것들을 나열하기만 하면 된다.
let n = Int(readLine()!)!
for i in 1...9 {
print(n, "*", i, "=", n * i)
}
10950 A+B - 3
숫자를 두 개 입력받아 합을 출력한다.
숫자가 작으므로 오버플로우는 신경쓰지 않아도 되고, T
를 받아 반복하니 그 부분만 주의한다.
import Foundation
let t = Int(readLine()!)!
for _ in 1...t {
let nums = readLine()!.components(separatedBy: " ").map{ Int($0)! }
print(nums[0] + nums[1])
}
8393 합
n
을 입력받아 n
까지의 합을 구한다.
가우스 합을 사용해도 되지만 반복문을 써보는 단계라서 일일이 더해주었다.
let n = Int(readLine()!)!
var sum = 0
for i in 1...n { sum += i }
print(sum)
15552 빠른 A+B
입출력 방식을 빠르게 해 두 수의 합을 구하는 문제다.
각 언어별로 빠르게 입출력을 할 수 있는 방법이 있는데 스위프트의 경우 readLine()
의 속도가 느려 fread
의 스위프트 버전을 만들어 사용한다. 라이노님이 작성하신 코드를 이용하는데 정확한 원리는 모르겠지만… 사용하니 시간초과 뜨던 문제가 바로 통과됐다.
// 라이노님이 만드신 FileIO 클래스
import Foundation
final class FileIO {
private let buffer:[UInt8]
private var index: Int = 0
init(fileHandle: FileHandle = FileHandle.standardInput) {
buffer = Array(try! fileHandle.readToEnd()!)+[UInt8(0)] // 인덱스 범위 넘어가는 것 방지
}
@inline(__always) private func read() -> UInt8 {
defer { index += 1 }
return buffer[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 now = read()
while now == 10 || now == 32 { now = read() } // 공백과 줄바꿈 무시
let beginIndex = index-1
while now != 10, now != 32, now != 0 { now = read() }
return String(bytes: Array(buffer[beginIndex..<(index-1)]), encoding: .ascii)!
}
@inline(__always) func readByteSequenceWithoutSpaceAndLineFeed() -> [UInt8] {
var now = read()
while now == 10 || now == 32 { now = read() } // 공백과 줄바꿈 무시
let beginIndex = index-1
while now != 10, now != 32, now != 0 { now = read() }
return Array(buffer[beginIndex..<(index-1)])
}
}
// 사용할 때
let fIO = FileIO() // 입력받는 인스턴스 생성
let n = fIO.readInt() // Int로 입력받기
// 15552 정답 코드
// 위 코드의 클래스 부분 + 아래 코드
let fio = FileIO()
let n = fio.readInt()
for _ in 0..<n {
var a = fio.readInt() + fio.readInt()
print(a)
}
2741 N 찍기
N
을 입력받아 1…N
을 출력한다.
let n = Int(readLine()!)!
for i in 1...n { print(i) }
2742 기찍 N
N
을 입력받아 N…1
을 출력한다.
세 가지 방법이 있다.
1…N
으로 범위를 주면 1부터 커지기만 한다. 거꾸로 쓰고 싶을 때는stride
함수를 이용해서시작점
,도착점
,더해갈 수
를 정해주면 된다.
stirde(from: N, to: 0, by: -1) { //실행 구문 }
// 아래와 같이 작동된다. to 미만인 점을 주의하자.
while (from < to) {
// 실행 구문
from += by
}
// 정답코드 1
let n = Int(readLine()!)!
for i in stride(from: n, to: 0, by: -1) { print(i) }
- 거꾸로 쓰는 법이 하나 더 있다. 정방향의 범위를 써준 후
reversed()
함수를 적용한다.reversed()
함수는 범위를 반대로 뒤집어준다.
// 정답코드 2
let n = Int(readLine()!)!
for i in (1...n).reversed() { print(i) }
0..<N
을 사용하고, 출력할 때N - i
를 사용한다.
// 정답코드 3
let n = Int(readLine()!)!
for i in 0..<n { print(n - i) }
11021 A+B - 7
입력받은 두 수의 합을 예쁘게 출력한다. 출력문에 몇 번째 케이스인지 보여줘야 한다.
문자열 보간법을 사용해 String
과 Int
들을 한 번에 출력해준다.
import Foundation
let t = Int(readLine()!)!
for i in 1...t {
let nums = readLine()!.components(separatedBy: " ").map{ Int($0)! }
print("Case #(i): (nums[0] + nums[1])")
}
11022 A+B - 8
위 문제와 거의 비슷하지만 이번에는 입력받은 숫자까지 같이 써준다.
import Foundation
let t = Int(readLine()!)!
for i in 1...t {
let nums = readLine()!.components(separatedBy: " ").map{ Int($0)! }
print("Case #(i): (nums[0]) + (nums[1]) = (nums[0] + nums[1])")
}
2438 별 찍기 - 1
n
번째 줄에 별을 n
개 찍는 문제다.
한 줄에 한 문자를 여러 번 적고, 여러 줄 반복하니 이중 for문
을 써야 한다.
문자를 반복할 때는 줄바꿈을 하지 않으니까 terminator
를 다시 설정해준다.
let n = Int(readLine()!)!
for i in 1...n {
for _ in 1...i {
print("*", terminator: "")
}
print("")
}
2439 별 찍기 - 2
위 문제와 거의 비슷하지만 이번에는 왼쪽에 공백을 둬 오른쪽 정렬한다.
공백의 개수와 별의 개수의 합이 n
임을 이용한다.
let n = Int(readLine()!)!
for i in 0..<n {
for _ in 1..<(n - i) { print(" ", terminator: "") }
for _ in 0...i { print("*", terminator: "") }
print("")
}
10871 X보다 작은 수
숫자 목록을 받아서 주어진 X
보다 작은 수들만 출력한다.
반복문을 돌 때 print
가 자동 개행을 하므로 terminator
를 다시 설정해주자.
import Foundation
// nums[0] = N, nums[1] = X
let nums = readLine()!.components(separatedBy: " ").map{ Int($0)! }
let a = readLine()!.components(separatedBy: " ").map{ Int($0)! }
for i in 0..<nums[0] {
if a[i] < nums[1] {
print(a[i], terminator: " ")
}
}
10952 A+B - 5
두 수의 합을 출력하는데, 입력으로 (0, 0)
이 들어올 때까지 계속 입력을 받는다.
무한 반복문을 돌면서 입력을 받고, 특정 입력이 들어오면 break
하게 했다.
while
의 조건식에는 bool
값이 들어가야 되는데, c++
에서 했던 거처럼 1
을 쓰니 오류가 나서 true
를 넣어주었다.
import Foundation
while true {
let nums = readLine()!.components(separatedBy: " ").map{ Int($0)! }
if nums[0] + nums[1] == 0 { break }
print(nums[0] + nums[1])
}
10951 A+B - 4
이번에는 입력이 없을 때까지 입력을 받는다.
readLine()
이 옵셔널 값이니 let 문
을 사용해 입력이 정상적으로 들어왔는지를 판단한다.
제출 전 실행해서 테스트 입력을 넣으면 다음 입력을 기다리는데, 아마 채점할 때는 EOF
를 줘서 입력을 끝낼 것이다. ctrl+D
로 EOF
를 주고 잘 종료된다면 제출하자.
import Foundation
while let input = readLine() {
let ns = input.components(separatedBy: " ").map{ Int($0)! }
print(ns[0] + ns[1])
}
1110 더하기 사이클
입력받은 수의 각 자리수를 더하고(한 자리 수면 자기 자신), 원래 숫자의 1의 자리 수
와 더한 수의 1의 자리 수
를 이어 새로운 수를 만든다. 이렇게 계속 진행하다가 처음에 입력받은 수가 되면 사이클이 된 것이고, 그 사이클의 길이를 구하면 된다.
처음 숫자로 돌아왔는지 검사해야되니 nc
(n copy)
라는 상수에 저장해두고, 적어도 한 번은 진행할 것이니 repeat while
문을 사용한다. 각 자리수를 따로 계속 사용하니 상수에 저장해둔다.
var n = Int(readLine()!)!
let nc = n
var cnt: Int = 0
repeat {
let a = n / 10
let b = n % 10
n = b * 10 + (a + b) % 10 // (원래 수 1의 자리를 10의 자리로) + (더한 수의 1의 자리)
cnt += 1
} while n != nc
print(cnt)
'알고리즘 > 문제풀이' 카테고리의 다른 글
[백준] (Swift) 2675 문자열 반복 (0) | 2022.07.11 |
---|---|
[백준](Swift) 1차원 배열 (0) | 2022.06.04 |
[백준](Swift) 조건문 (0) | 2022.05.13 |
[백준](Swift) 입출력과 사칙연산 (2) | 2022.05.10 |
[백준] (C++) 5567 - 결혼식 (0) | 2022.01.12 |
댓글