처음에는 이중 반복문을 돌면서 각 숫자를 음수로 바꾼 후의 총 합이 타겟과 같은지 판별하는 로직으로 구현했다가 실패
-> +4-1+2-1 과 같이 음수 사이에 양수가 존재하는 경우는 고려할 수 없음
각 숫자가 양수이거나 음수인 경우만 고려하면 되고 그러면 2^N의 시간 복잡도가 발생하는데, N의 최대값은 20으로 약 1,050,000이 됨
각 숫자가 양수이거나 음수가 되는 경우를 모두 고려하려면 각 숫자에 +,-를 붙인 노드로 이루어진 트리로 시각화할 수 있음
각 노드를 탐색하며 더한 합계값을 타겟 넘버와 비교하면 결과값 도출 가능
탐색에는 BFS/DFS를 모두 사용할 수 있으나 제출 코드는 BFS사용
코드구현 (스위프트사용)
import Foundation
funcsolution(_numbers:[Int], _target:Int) -> Int {
var result =0var sum_arr = [0] // 반복문 시작을 위해 0 하나 추가for n in numbers {
var temp: [Int] = []
for s in sum_arr {
temp.append(s+n)
temp.append(s-n)
}
sum_arr = temp
}
for s in sum_arr { result += (s == target) ?1 : 0 }
return result
}
n명에게 각각 예상 등수값을 입력받고, 그 값들을 토대로 불만족 지수가 최소로 나오도록 구성하여 불만족 지수의 최소값을 출력
불만족 지수란 예상 등수가 1등이고, 실제 순위 구성 후 등수가 3등인 경우 (|1-3|)으로 2의 값이 됨
(n의 범위는 1이상 500,000이하)
풀이법 구상
예상 순위보다 실제 순위가 높든 낮든 무관하게 그 차이값만큼이 불만족 수치가 됨
최대한 예상 순위가 실제 순위가 되도록 해야하므로 정렬 후 각 예상 순위값을 돌며 실제 순위와의 차이값을 구해야함
정렬 + 반복문이 필요함
-> 스위프트 기본 정렬 메소드의 시간복잡도 - O(n log n)
-> 반복문 시간 복잡도 - O(N)
-> 동시에 일어나지 않고 정렬 후 반복문 돌게됨
코드구현 (스위프트사용)
import Foundation
funcsolution(_arr: [Int]) -> Void {
var sum =0let temp = arr.sorted()
for i in1...arr.count { sum +=abs(i - temp[i-1]) }
print(sum)
}
var arr: [Int] = []
let cnt =Int(readLine()!)!for_in0..<cnt { arr.append(Int(readLine()!)!) }
solution(arr)
-> 기본 정렬 메소드의 시간 복잡도는 O(n log n) 이므로 시간 제한에 문제되지않음
코드 구현 (스위프트 사용)
import Foundation
funcsolution(_arr: [Int]) -> Void {
let result = arr.sorted()
for n in result { print(n) }
}
var arr: [Int] = []
let cnt =Int(readLine()!)!for_in0..<cnt { arr.append(Int(readLine()!)!) }
solution(arr)
주어진 두 수 m, n을 포함하여 그 사이에 존재하는 소수의 합계값과 그 소수들 중 최소값을 출력 (소수가 없는 경우 -1 출력)
풀이법 구상
m이상 n이하를 범위로 하는 반복문을 돌면서 각 수가 소수인지 판별
코드 구현 (스위프트 사용)
import Foundation
func solution(_ m:Int, _ n:Int) -> Void {
var sum = 0
var min = -1
for p in m...n {
if isDecimal(p) {
sum += p
if (min == -1 || min > p) { min = p }
}
}
if (sum == 0) { print(-1) }
else {
print(sum)
print(min)
}
}
func isDecimal(_ n:Int) -> Bool {
if (n == 1) { returnfalse }
for i in 2..<n { if (n%i == 0) { returnfalse } }
returntrue
}
let m = Int(readLine()!)!
let n = Int(readLine()!)!
solution(m,n)
lazyvar leftTitleLabel1 = getLabelView(titleStr: "서울특별시", fontSize: 20.0, fontWeight: .bold, fontColor: .white)
lazyvar leftTitleLabel2 = getLabelView(titleStr: "9°", fontSize: 40.0, fontWeight: .medium, fontColor: .white)
lazyvar leftStackView =UIStackView().then {
$0.backgroundColor = .green
// 스택 요소로 포함할 subView들을 선언let stackView =UIStackView(arrangedSubviews: [leftTitleLabel1, leftTitleLabel2])
$0.axis = .vertical // 수직 방향으로 스택을 구성$0.distribution = .fill // 요소들이 스택을 채울 수 있게 분포되도록 구성$0.alignment = .leading // 왼쪽 끝에 붙어서 요소가 나열되도록 구성$0.spacing =0// 요소 간의 간격 0
}
// helper methods - 컨테이너 뷰를 가진 UILabel 컴포넌트를 반환funcgetLabelView(titleStr: String, fontSize: Double, fontWeight: UIFont.Weight, fontColor: UIColor) -> UIView {
let titleLabel =UILabel().then {
$0.text = titleStr
$0.font = .systemFont(ofSize: fontSize, weight: fontWeight)
$0.textColor = fontColor
}
let containerView =UIView().then {
$0.backgroundColor = .systemPink
$0.backgroundColor = .clear
}
containerView.addSubview(titleLabel)
titleLabel.snp.makeConstraints { make in
make.top.bottom.leading.trailing.equalToSuperview()
}
return containerView
}
2-3. 우측 상단의 구름 이미지, 날씨, 최고/최저 기온을 포함한 수직 UIStackView
let cloudImgView =UIImageView(image: UIImage(systemName: "cloud.fill")).then {
$0.tintColor = .white
}
// getLabelView는 상단 helper method 참조lazyvar rightTitleLabel1 = getLabelView(titleStr: "대체로 흐림", fontSize: 18.0, fontWeight: .medium, fontColor: .white)
lazyvar rightTitleLabel2 = getLabelView(titleStr: "최고: 21° 최저 7°", fontSize: 18.0, fontWeight: .medium, fontColor: .white)
lazyvar rightStackView =UIStackView().then {
$0.backgroundColor = .blue
let stackView =UIStackView(arrangedSubviews: [cloudImgView, rightTitleLabel1, rightTitleLabel2])
$0.axis = .vertical
$0.distribution = .fill
$0.alignment = .trailing // 요소들이 오른쪽 끝에 붙어 나열될 수 있도록 구성$0.spacing =3
}
좌우측 상단에 스택뷰를 추가한 후
2-4. - 하단의 각 시간대별 날씨를 포함한 수평 UIStackView
let weatherWithTimeList = [
["오전 8시", "10°"],
["오전 9시", "12°"],
["오전 10시", "15°"],
["오전 11시", "17°"],
["오후 12시", "19°"],
["오후 1시", "20°"],
]
lazyvar weatherViews: [UIView] = []
// helper method - 시간 및 기온 정보 배열을 토대로 하단 수평 스택뷰의 요소로 쓰이는 UIView 반환// viewDidLoad 내에서 호출하여 weatherViews 배열 구성funcconfigureWeatherOfTime() {
weatherWithTimeList.map { info in
weatherViews.append(getWeatherViewOfTime(timeStr: info[0], temper: info[1]))
}
}
lazyvar bottomStackView =UIStackView().then {
let stackView =UIStackView(arrangedSubviews: weatherViews)
$0.axis = .horizontal // 수평 방향으로 요소가 나열되도록 지정$0.distribution = .fillEqually // 모든 요소가 스택 내에서 동등한 크기를 가지도록 지정$0.alignment = .leading
$0.spacing =5
}
하단 스택뷰를 추가한 후
3. 레이아웃 구성
privatefuncsetLayouts() {
// add viewsself.view.addSubview(backView)
// 전체 컨테이너 뷰에 좌측 상단, 우측 상단, 하단 스택뷰를 추가
backView.addSubview(leftStackView)
backView.addSubview(rightStackView)
backView.addSubview(bottomStackView)
// add views in StackView// 좌측 상단 스택뷰 내에 요소로 사용될 sub view들을 추가
leftStackView.addArrangedSubview(leftTitleLabel1)
leftStackView.addArrangedSubview(leftTitleLabel2)
// 우측 상단 스택뷰 내에 요소로 사용될 sub view들을 추가
rightStackView.addArrangedSubview(cloudImgView)
rightStackView.addArrangedSubview(rightTitleLabel1)
rightStackView.addArrangedSubview(rightTitleLabel2)
// 하단 스택뷰 내에 요소로 사용될 sub view들을 추가
weatherViews.map { view in
bottomStackView.addArrangedSubview(view)
}
// set constraints
backView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(130)
make.leading.equalToSuperview().offset(20)
make.trailing.equalToSuperview().inset(20)
}
leftStackView.snp.makeConstraints { make in
make.leading.top.equalToSuperview().offset(15)
}
cloudImgView.snp.makeConstraints { make in
make.top.equalToSuperview()
}
rightStackView.snp.makeConstraints { make in
make.top.trailing.equalToSuperview().inset(15)
make.bottom.equalTo(leftStackView.snp.bottom)
}
bottomStackView.snp.makeConstraints { make in
make.top.equalTo(leftStackView.snp.bottom).offset(30)
make.leading.trailing.equalToSuperview().inset(10)
make.bottom.equalToSuperview().inset(15)
}
}
4. 추가) 수직 스택뷰 요소 간 spacing 달리 주기
// 구름 이미지 UIImageView를 감싸는 컨테이너 뷰 정의let cloudImgContainerView =UIView().then {
$0.backgroundColor = .clear
}
let cloudImgView =UIImageView(image: UIImage(systemName: "cloud.fill")).then {
$0.tintColor = .white
$0.contentMode = .scaleAspectFill
}
// 레이아웃 구성 변경
cloudImgView.snp.makeConstraints { make in
make.top.bottom.leading.trailing.equalToSuperview()
}
// 구름 이미지 컴포넌트 하단 요소에 대해 top 방향으로 원하는 만큼의 여백값을 추가
rightTitleLabel1.snp.makeConstraints { make in
make.top.equalTo(cloudImgView.snp.bottom).offset(20)
}