입력

첫째 줄에는 도감에 수록되어 있는 포켓몬의 개수 N이랑 내가 맞춰야 하는 문제의 개수 M이 주어져. N과 M은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수인데, 자연수가 뭔지는 알지? 모르면 물어봐도 괜찮아. 나는 언제든지 질문에 답해줄 준비가 되어있어.

둘째 줄부터 N개의 줄에 포켓몬의 번호가 1번인 포켓몬부터 N번에 해당하는 포켓몬까지 한 줄에 하나씩 입력으로 들어와. 포켓몬의 이름은 모두 영어로만 이루어져있고, 또, 음... 첫 글자만 대문자이고, 나머지 문자는 소문자로만 이루어져 있어. 아참! 일부 포켓몬은 마지막 문자만 대문자일 수도 있어. 포켓몬 이름의 최대 길이는 20, 최소 길이는 2야. 그 다음 줄부터 총 M개의 줄에 내가 맞춰야하는 문제가 입력으로 들어와. 문제가 알파벳으로만 들어오면 포켓몬 번호를 말해야 하고, 숫자로만 들어오면, 포켓몬 번호에 해당하는 문자를 출력해야해. 입력으로 들어오는 숫자는 반드시 1보다 크거나 같고, N보다 작거나 같고, 입력으로 들어오는 문자는 반드시 도감에 있는 포켓몬의 이름만 주어져. 그럼 화이팅!!!

출력

첫째 줄부터 차례대로 M개의 줄에 각각의 문제에 대한 답을 말해줬으면 좋겠어!!!. 입력으로 숫자가 들어왔다면 그 숫자에 해당하는 포켓몬의 이름을, 문자가 들어왔으면 그 포켓몬의 이름에 해당하는 번호를 출력하면 돼. 그럼 땡큐~

이게 오박사님이 나에게 새로 주시려고 하는 도감이야. 너무 가지고 싶다ㅠㅜ. 꼭 만점을 받아줬으면 좋겠어!! 파이팅!!!

풀이

1. Dictionary에 포켓몬번호와 이름 저장

2. Array에 포켓몬번호 index에 맞게 이름 저장

3. 포켓몬이름이 주어지면 Dictionary에서 value, 번호가 주어지면 Array에서 출력

 

Dictionary 단일로 저장하고 filter를 이용해 key값을 불러왔는데 시간초과가 떴다

더 줄이는 방법으로 아예 두가지 컬렉션으로 접근하는 방식을 이용했다

 

import Foundation

let inputs = readLine()!.split(separator:" ").map{ Int(String($0))!}
var pokemonsDict = [String: Int]()
var pokemonsArr = Array(repeating: "", count: inputs[0]+1)

for i in 1...inputs[0] {
    let pokemon = readLine()!
    pokemonsDict[pokemon] = i
    pokemonsArr[i] = pokemon
}

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

    if Int(quest) == nil {
        print(pokemonsDict[quest]!)
    } else {
        print(pokemonsArr[Int(quest)!])
    }
}

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

BOJ-1764 듣보잡 Swift  (0) 2023.04.06
BOJ-10816 숫자카드 2 Swift  (0) 2023.04.06
BOJ-7785 회사에 있는 사람 Swift  (0) 2023.04.06
BOJ-14425 문자열 집합 Swift  (0) 2023.04.06
BOJ-10815 숫자 카드 Swift  (0) 2023.04.06

문제

상근이는 세계적인 소프트웨어 회사 기글에서 일한다. 이 회사의 가장 큰 특징은 자유로운 출퇴근 시간이다. 따라서, 직원들은 반드시 9시부터 6시까지 회사에 있지 않아도 된다.

각 직원은 자기가 원할 때 출근할 수 있고, 아무때나 퇴근할 수 있다.

상근이는 모든 사람의 출입카드 시스템의 로그를 가지고 있다. 이 로그는 어떤 사람이 회사에 들어왔는지, 나갔는지가 기록되어져 있다. 로그가 주어졌을 때, 현재 회사에 있는 모든 사람을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 로그에 기록된 출입 기록의 수 n이 주어진다. (2 ≤ n ≤ 106) 다음 n개의 줄에는 출입 기록이 순서대로 주어지며, 각 사람의 이름이 주어지고 "enter"나 "leave"가 주어진다. "enter"인 경우는 출근, "leave"인 경우는 퇴근이다.

회사에는 동명이인이 없으며, 대소문자가 다른 경우에는 다른 이름이다. 사람들의 이름은 알파벳 대소문자로 구성된 5글자 이하의 문자열이다.

출력

현재 회사에 있는 사람의 이름을 사전 순의 역순으로 한 줄에 한 명씩 출력한다.

풀이

1. 출입 기록 순서대로 주어지는 n개의 이름과 기록을 Dictionary에 저장 및 출입자 이름을 Set에 저장

2. Set에 저장된 출입자들 중 Dictionary에 대입해 "enter" 상태인 출입자들만 출력

 

import Foundation

let num = Int(readLine()!)!
var enterPersonDict = [String: String]()
var enteredPersonSet = Set<String>()

for i in 0..<num {
    let inputs = readLine()!.split(separator: " ").map{String($0)}
    enteredPersonSet.insert(inputs[0])
    enterPersonDict[inputs[0]] = inputs[1]
}

print(enteredPersonSet.filter{ enterPersonDict[$0] == "enter"}.sorted{ $0 > $1}.joined(separator: " "))

문제

총 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

+ Recent posts