문제

총 N개의 문자열로 이루어진 집합 S가 주어진다.

입력으로 주어지는 M개의 문자열 중에서 집합 S에 포함되어 있는 것이 총 몇 개인지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 문자열의 개수 N과 M (1 ≤ N ≤ 10,000, 1 ≤ M ≤ 10,000)이 주어진다. 

다음 N개의 줄에는 집합 S에 포함되어 있는 문자열들이 주어진다.

다음 M개의 줄에는 검사해야 하는 문자열들이 주어진다.

입력으로 주어지는 문자열은 알파벳 소문자로만 이루어져 있으며, 길이는 500을 넘지 않는다. 집합 S에 같은 문자열이 여러 번 주어지는 경우는 없다.

출력

첫째 줄에 M개의 문자열 중에 총 몇 개가 집합 S에 포함되어 있는지 출력한다.

풀이

1. 문자열을 Set에 저장

2. 검사해야할 문자열을 for로 검사 

 

역시나 2중 for문으로 검사하면 시간 초과가 떴다

이전까지 복잡하게 생각했지만 단순하게 시간을 줄여서 접근해보았다

array.contains는 O(n) 이지만 set.contains 은 O(1)이여서 Set을 이용했다

문자열 비교와 정렬은 쉽게 시간초과가 많이 일어나서 고차함수와 Set, Dictionary를 알맞게 사용해야겠다

 

import Foundation

let inputs = readLine()!.split(separator: " ").map{ Int(String($0))!}
var strs = Set<String>()
var count = 0

for i in 0..<inputs[0] {
    let str = readLine()!
    strs.insert(str)
}

for j in 0..<inputs[1] {
    let str = readLine()!

    if strs.contains(str) {
        count += 1
    }
}

print(count)

 

 

 

문제

숫자 카드는 정수 하나가 적혀져 있는 카드이다. 상근이는 숫자 카드 N개를 가지고 있다. 정수 M개가 주어졌을 때, 이 수가 적혀있는 숫자 카드를 상근이가 가지고 있는지 아닌지를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다. 두 숫자 카드에 같은 수가 적혀있는 경우는 없다.

셋째 줄에는 M(1 ≤ M ≤ 500,000)이 주어진다. 넷째 줄에는 상근이가 가지고 있는 숫자 카드인지 아닌지를 구해야 할 M개의 정수가 주어지며, 이 수는 공백으로 구분되어져 있다. 이 수도 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다

출력

첫째 줄에 입력으로 주어진 M개의 수에 대해서, 각 수가 적힌 숫자 카드를 상근이가 가지고 있으면 1을, 아니면 0을 공백으로 구분해 출력한다.

풀이

1. 입력받은 수를 dict에 저장 

2. 저장된 dict값을 주어진 M개의 정수 배열에 대입  ( dict에 저장되어 있지 않으면 0, 있으면 1)

입력받는 수 M의 범위가 매우 커서 시간이 매우 빠듯하게 주어질꺼라 예상했는데

역시나 for문 안에서 Array.contains 를 이용하여 배열순회를 돌리니 시간초과가 떴다 ( O(n^2))

가져온 M개의 배열을 dict의 value로 변환하여 출력하니까 시간초과가 안떴다

 

 

let cardNum = Int(readLine()!)!
let cards = readLine()!.split(separator: " ").map{ Int(String($0))!}
let getCardCount = Int(readLine()!)!
var getCards = readLine()!.split(separator: " ").map{ Int(String($0))!}

var dict = [Int: Int]()

for i in cards {
    dict[i] = 1
}

print(getCards.map{ (num: Int) -> Int in
    if dict[num] == nil {
        return 0
    } else {
        return 1
    }
}.map{String($0)}.joined(separator: " "))

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

BOJ-7785 회사에 있는 사람 Swift  (0) 2023.04.06
BOJ-14425 문자열 집합 Swift  (0) 2023.04.06
BOJ-18870 좌표 압축 Swift  (0) 2023.04.06
BOJ-10814 나이순 정렬 Swift  (0) 2023.04.05
BOJ-1181 단어 정렬 Swift  (0) 2023.04.05

문제

수직선 위에 N개의 좌표 X1, X2, ..., XN이 있다. 이 좌표에 좌표 압축을 적용하려고 한다.

Xi를 좌표 압축한 결과 X'i의 값은 Xi > Xj를 만족하는 서로 다른 좌표의 개수와 같아야 한다.

X1, X2, ..., XN에 좌표 압축을 적용한 결과 X'1, X'2, ..., X'N를 출력해보자.

입력

첫째 줄에 N이 주어진다.

둘째 줄에는 공백 한 칸으로 구분된 X1, X2, ..., XN이 주어진다.

출력

첫째 줄에 X'1, X'2, ..., X'N을 공백 한 칸으로 구분해서 출력한다.

풀이

x1 좌표를 압축한다 -> 주어진 좌표중에서 x1좌표보다 작은 좌표의 개수로 변환됨

-> 입력받은 x좌표를 배열로 만들어 오름차순으로 정렬 했을 때 인덱스 값이 곧 압축값이다

 

배열로 입력받으면 중복값이 있으므로 아예 인덱스를 구할땐 Set으로 변환했다

그리고 바로 map 고차함수를 사용하기위해 dict에 넣어두었다.

이 문제는 시간이 매우촉박해서 최대한 시간을 줄였어야했다

 

let input = Int(readLine()!)!
var nums = readLine()!.split(separator: " ").map{ Int(String($0))! }
var sortedSet = Set(nums).sorted{ $0 < $1}.enumerated()
var dict = [ Int: Int]()

for (index, number) in sortedSet {
    dict[number] = index
}
print(nums.map{ String(dict[$0]!)}.joined(separator: " "))

 

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

BOJ-14425 문자열 집합 Swift  (0) 2023.04.06
BOJ-10815 숫자 카드 Swift  (0) 2023.04.06
BOJ-10814 나이순 정렬 Swift  (0) 2023.04.05
BOJ-1181 단어 정렬 Swift  (0) 2023.04.05
BOJ-11650,11651 좌표 정렬하기 Swift  (0) 2023.04.05

문제

온라인 저지에 가입한 사람들의 나이와 이름이 가입한 순서대로 주어진다. 이때, 회원들을 나이가 증가하는 순으로, 나이가 같으면 먼저 가입한 사람이 앞에 오는 순서로 정렬하는 프로그램을 작성하시오.

입력

첫째 줄에 온라인 저지 회원의 수 N이 주어진다. (1 ≤ N ≤ 100,000)

둘째 줄부터 N개의 줄에는 각 회원의 나이와 이름이 공백으로 구분되어 주어진다. 나이는 1보다 크거나 같으며, 200보다 작거나 같은 정수이고, 이름은 알파벳 대소문자로 이루어져 있고, 길이가 100보다 작거나 같은 문자열이다. 입력은 가입한 순서로 주어진다.

출력

첫째 줄부터 총 N개의 줄에 걸쳐 온라인 저지 회원을 나이 순, 나이가 같으면 가입한 순으로 한 줄에 한 명씩 나이와 이름을 공백으로 구분해 출력한다.

풀이

1. 입력순서와 나이 이름을 배열에 넣는다

2. 2차원배열에 넣어서 나이순으로 정렬한다

3. 나이가 같으면 입력순으로 정렬한다

 

 

import Foundation

func test() {
    guard let input = Int(readLine()!) else {return}
    var list = [[String]]()
    
    for i in 1...input {
        guard let str = readLine()?.split(separator: " ") else {return}
        var arr = str.map{ String($0)}
        arr.insert(String(i), at: 0)
        
        list.append(arr)
    }
    list.sort{ if Int($0[1]) == Int($1[1]) {
        return Int($0[0])! < Int($1[0])!
    } else {
        return Int($0[1])! < Int($1[1])!
    }}
    

    for i in list {
        var arr = i
        arr.removeFirst()
        print(arr.joined(separator: " "))
    }
}
test()

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

BOJ-10815 숫자 카드 Swift  (0) 2023.04.06
BOJ-18870 좌표 압축 Swift  (0) 2023.04.06
BOJ-1181 단어 정렬 Swift  (0) 2023.04.05
BOJ-11650,11651 좌표 정렬하기 Swift  (0) 2023.04.05
BOJ-1427 소트인사이드 Swift  (0) 2023.04.05

문제

알파벳 소문자로 이루어진 N개의 단어가 들어오면 아래와 같은 조건에 따라 정렬하는 프로그램을 작성하시오.

  1. 길이가 짧은 것부터
  2. 길이가 같으면 사전 순으로

단, 중복된 단어는 하나만 남기고 제거해야 한다.

입력

첫째 줄에 단어의 개수 N이 주어진다. (1 ≤ N ≤ 20,000) 둘째 줄부터 N개의 줄에 걸쳐 알파벳 소문자로 이루어진 단어가 한 줄에 하나씩 주어진다. 주어지는 문자열의 길이는 50을 넘지 않는다.

출력

조건에 따라 정렬하여 단어들을 출력한다.

풀이

1. 길이가 같으면 사전순, 다르면 길이수의 오름차순으로 정렬한다

2. 정렬된 대로 출력한다.

 

앞서 11650번 문제의 좌표정렬하기에서 2차원 배열을 sort로 정렬하여 출력했었다.

같은 방법으로 string을 받아 길이 비교 후 사전순으로 정렬을 했는데 시간 초과가 떴다

더이상 시간을 줄일 수 없어서 배열 보다 빠른 Set 을 사용했다

 

Set은 

1. 정렬되지 않은 컬렉션

2. 중복된 요소를 허용하지않는다

3. 해시를 통해 값을 저장

 -> 배열에 비해 검색 속도가 빠르다.

4. 저장되는 자료형은 Hashable 프로토콜 준수

 

이 문제를 풀땐 배열보다 빠르다는 장점만 보고 사용했다

아슬아슬 하게 시간초과는 면했다

 

import Foundation

func test() {
    guard let input = Int(readLine()!) else {return}
    var strSet = Set<String>()
    for i in 0..<input {
        guard let str = readLine() else {return}
        strSet.insert(str)
    }
    var sortedSet = strSet.sorted{ if $0.count == $1.count {
        return $0 < $1
    } else {
        return $0.count < $1.count
    }}
    for i in sortedSet {
        print(i)
    }
}
test()

 

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

BOJ-18870 좌표 압축 Swift  (0) 2023.04.06
BOJ-10814 나이순 정렬 Swift  (0) 2023.04.05
BOJ-11650,11651 좌표 정렬하기 Swift  (0) 2023.04.05
BOJ-1427 소트인사이드 Swift  (0) 2023.04.05
BOJ-1436 영화감독 숌 Swift  (0) 2023.04.05

문제

2차원 평면 위의 점 N개가 주어진다. 좌표를 x좌표가 증가하는 순으로, x좌표가 같으면 y좌표가 증가하는 순서로 정렬한 다음 출력하는 프로그램을 작성하시오.

 

입력

첫째 줄에 점의 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에는 i번점의 위치 xi와 yi가 주어진다. (-100,000 ≤ xi, yi ≤ 100,000) 좌표는 항상 정수이고, 위치가 같은 두 점은 없다.

 

출력

첫째 줄부터 N개의 줄에 점을 정렬한 결과를 출력한다.

 

풀이

1.  x좌표를 오름차순으로 정렬한다.

2. x좌표가 같을 경우 y좌표를 오름차순으로 정렬한다.

 

- 2중 for문으로 index 값을 확인해서 insert 로 넣은 결과 시간초과가 떴다. 시간복잡도 O(n^2)

func test() { 	// 시간초과 N^2
    guard let count = Int(readLine()!) else { return }
    var nums = [[Int]]()

    for i in 0..<count {
        guard let input = readLine()?.split(separator: " ") else { return }
        var arr = input.map{ Int(String($0))!}
        var index = 0

        if nums.isEmpty {
            nums.append(arr)
            continue
        }

        for j in 0..<nums.count {
            let x1 = nums[j][0]
            let y1 = nums[j][1]
            let x2 = arr[0]
            let y2 = arr[1]

            if x1 < x2 {
                if j == nums.count - 1 {
                    index = nums.count
                }
                continue
            } else if x1 == x2 {
                if y1 < y2 {
                    index = j+1
                } else {
                    index = j
                }
                break
            } else {
                index = j
                break
            }
        }
        nums.insert(arr, at: index)
    }

    for j in nums {
        print(j.map{ String($0)}.joined(separator: " "))
    }

}

test()

 

시간제한 1초 였던 문제라 시간 복잡도를 좀  줄였어야했다.

그래서 array 함수중 sort를 이용했다. sort의 시간복잡도는 O(nlogn)으로 2중 배열보다 빨랐다.

하지만 sort 함수를 사용해서 2차원배열 y좌표 접근하는 방법은 아직 미숙했다.

< 11650 >

func test() {
    guard let input = Int(readLine()!) else {return}
    var nums = [[Int]]()
    
    for i in 0..<input {
        guard let inputs = readLine()?.split(separator: " ") else {return}
        var arr = inputs.map{ Int(String($0))!}
        nums.append(arr)
    }
    nums = nums.sorted{ if $0[0] == $1[0] {
        return $0[1] < $1[1]
    } else {
        return $0[0] < $1[0]
    }}
    
    for j in nums {
        print(j.map{ String($0)}.joined(separator: " "))
    }
}
test()

마지막 출력할때 사용된 map함수의 시간복잡도는 O(n)이므로 결국 n + nlogn 이므로 n^2 보다 빠르니 시간초과가 뜨지않았다

 

11651 은 정렬기준만 다르기때문에 위 코드와 큰 차이는 없었다

< 11651 >

import Foundation

func test() {
    guard let input = Int(readLine()!) else {return}
    var nums = [[Int]]()
    
    for i in 0..<input {
        guard let inputs = readLine()?.split(separator: " ") else {return}
        var arr = inputs.map{ Int(String($0))!}
        nums.append(arr)
    }
    nums = nums.sorted{ if $0[1] == $1[1] {
        return $0[0] < $1[0]
    } else {
        return $0[1] < $1[1]
    }}
    
    for j in nums {
        print(j.map{ String($0)}.joined(separator: " "))
    }
}
test()

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

BOJ-10814 나이순 정렬 Swift  (0) 2023.04.05
BOJ-1181 단어 정렬 Swift  (0) 2023.04.05
BOJ-1427 소트인사이드 Swift  (0) 2023.04.05
BOJ-1436 영화감독 숌 Swift  (0) 2023.04.05
BOJ-1018 체스판 다시칠하기 Swift  (0) 2023.03.31

문제

배열을 정렬하는 것은 쉽다. 수가 주어지면, 그 수의 각 자리수를 내림차순으로 정렬해보자.

입력

첫째 줄에 정렬하려고 하는 수 N이 주어진다. N은 1,000,000,000보다 작거나 같은 자연수이다.

출력

첫째 줄에 자리수를 내림차순으로 정렬한 수를 출력한다.

풀이

1. 입력받은 수를 Int 배열로 바꾼다

2. 배열을 내림차순으로 정렬한다 sort

3. 정렬된 배열을 String 배열로 바꾼뒤 String으로 변환한다 joined

 

import Foundation

func test() {
    guard let input = readLine() else { return }
    var nums = Array(input).map{ Int(String($0))!}
    nums.sort{ $0 > $1 }
    print(nums.map{ String($0)}.joined(separator: ""))
}

test()

문제

 

666은 종말을 나타내는 수라고 한다. 따라서, 많은 블록버스터 영화에서는 666이 들어간 제목을 많이 사용한다. 영화감독 숌은 세상의 종말 이라는 시리즈 영화의 감독이다. 조지 루카스는 스타워즈를 만들 때, 스타워즈 1, 스타워즈 2, 스타워즈 3, 스타워즈 4, 스타워즈 5, 스타워즈 6과 같이 이름을 지었고, 피터 잭슨은 반지의 제왕을 만들 때, 반지의 제왕 1, 반지의 제왕 2, 반지의 제왕 3과 같이 영화 제목을 지었다. 하지만 숌은 자신이 조지 루카스와 피터 잭슨을 뛰어넘는다는 것을 보여주기 위해서 영화 제목을 좀 다르게 만들기로 했다.

종말의 수란 어떤 수에 6이 적어도 3개 이상 연속으로 들어가는 수를 말한다. 제일 작은 종말의 수는 666이고, 그 다음으로 큰 수는 1666, 2666, 3666, .... 이다. 따라서, 숌은 첫 번째 영화의 제목은 "세상의 종말 666", 두 번째 영화의 제목은 "세상의 종말 1666"와 같이 이름을 지을 것이다. 일반화해서 생각하면, N번째 영화의 제목은 세상의 종말 (N번째로 작은 종말의 수) 와 같다.

숌이 만든 N번째 영화의 제목에 들어간 수를 출력하는 프로그램을 작성하시오. 숌은 이 시리즈를 항상 차례대로 만들고, 다른 영화는 만들지 않는다.

입력

첫째 줄에 N이 주어진다. N은 10,000보다 작거나 같은 자연수이다.

출력

첫째 줄에 N번째 영화의 제목에 들어간 수를 출력한다.

 

 

풀이

1. 666이 가장 작은 종말의 수로 666부터 시작한다

2. 666이 연속되고, 연속된 666의 갯수가 1번인 경우만 배열에 넣는다 ( 6660666 x)

3. 입력받은 수 ( N번째로 작은 종말의 수) 만큼 배열에 찼다면, 배열의 마지막수를 출력한다

 

 

import Foundation

func test() {
    guard let index = Int(readLine()!) else { return }
    
    var num = 666
    var nums = [Int]()
    
    while nums.count < index {
        var number = num
        var sixCount = 0
        var tripleCount = 0
        
        while number > 0 {
            
            if number % 10 == 6 {
                sixCount += 1
            } else {
                sixCount = 0
            }
            
            if sixCount == 3 {
                tripleCount += 1
                
            }
            number = number / 10
        }
        
        if tripleCount == 1 {
            nums.append(num)
        }
        num += 1
        
    }
    print(nums.last!)

}

test()

 

 

+ Recent posts