티스토리 뷰

백준/백준 - 스위프트

1931번: 회의실 배정

강철곰탱이 2023. 11. 28. 20:38

 

 

1931번: 회의실 배정

(1,4), (5,7), (8,11), (12,14) 를 이용할 수 있다.

www.acmicpc.net

 

회의실 배정 

 

문제

한 개의 회의실이 있는데 이를 사용하고자 하는 N개의 회의에 대하여 회의실 사용표를 만들려고 한다. 각 회의 I에 대해 시작시간과 끝나는 시간이 주어져 있고, 각 회의가 겹치지 않게 하면서 회의실을 사용할 수 있는 회의의 최대 개수를 찾아보자. 단, 회의는 한번 시작하면 중간에 중단될 수 없으며 한 회의가 끝나는 것과 동시에 다음 회의가 시작될 수 있다. 회의의 시작시간과 끝나는 시간이 같을 수도 있다. 이 경우에는 시작하자마자 끝나는 것으로 생각하면 된다.

입력

첫째 줄에 회의의 수 N(1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N+1 줄까지 각 회의의 정보가 주어지는데 이것은 공백을 사이에 두고 회의의 시작시간과 끝나는 시간이 주어진다. 시작 시간과 끝나는 시간은 231-1보다 작거나 같은 자연수 또는 0이다.

출력

첫째 줄에 최대 사용할 수 있는 회의의 최대 개수를 출력한다.

예제 입력 1 

11
1 4
3 5
0 6
5 7
3 8
5 9
6 10
8 11
8 12
2 13
12 14

예제 출력 1 

4
 

 


 

풀이

 

이 문제는 알고리즘 해결 전략 10장 탐욕법의 예시로 나오는 문제이다.

 

 

[Algorithm Strategy] - 10. 탐욕법

📝 목차 1. 도입 2. 문제: 도시락 데우기(문제 ID: LUNCHBOX, 난이도: 하) 3. 문제: 문자열 합치기(문제 ID: STRJOIN, 난이도: 중) 1. 도입 탐욕법은 가장 직관적인 알고리즘이라고 할 수 있다. 재귀호출과

steelbeartaeng2.tistory.com

 

일단 문제를 확인해보자.

 

  • 한 개의 회의실에 N개의 회의로 회의실 사용표를 만든다.
  • 각 회의가 겹치지 않으면서 최대로 사용할 수 있는 회의 최대 개수를 구하라.

 

여기서 탐욕법을 적용할 수 있다.

탐욕법은 각 단계마다 가장 좋은 방법을 택하는 것으로, 이 문제에서는 각 회의 중에 빨리 끝나는 회의를 선택하여 최대 회의 개수를 구할 수 있을 것 같다.

 

 


설계

 

 

 

그럼 탐욕법에 의해 각 단계마다 빨리 끝나는 회의를 구해보자.

 

각 단계마다 빨리 끝나는 회의는 현재 진행중인 회의의 끝 시간과 가장 가까운 시작 시간을 가진 회의를 선택하면 된다.

다음과 같이 설계할 수 있다.

 

  1. 끝 시간에 따라 오름차순 정렬
  2. 현재 진행중인 회의의 끝 시간보다 이후의 시작 시간을 가진 회의 찾기
  3. 찾을 때마다 최대 회의 개수 증가 

 

 


구현

 

위의 설계를 바탕으로 구현하였다.

 

 

 

하지만 85%정도에서 틀렸다. ㅎ

왜일까 생각하니 반례가 있었다.

 

let N = Int(readLine()!)!

var arr = [[Int]](repeating: [Int](repeating: 0, count: 2), count: N)

for i in 0..<N{
    let input = readLine()!.split(separator: " ").map{Int(String($0))!}
    
    arr[i][0] = input[0]
    arr[i][1] = input[1]
    
}

arr.sort { $0[1] < $1[1] }

var result = 0
var current = 0
for i in 0..<N{
    let begin = arr[i][0]
    let end = arr[i][1]
    
    if current <= begin{
        current = end
        result += 1
    }else{
        continue
    }
}

print(result)

 

 

반례는 다음과 같다.

 

3
5 5
3 5
2 5

//result = 2

 

여기서 결과값은 2가 나와야 하지만 위의 코드로는 1이 나오게 된다. 뭔가 잘못된 것을 알 수 있다.

 

2~5동안 진행하는 회의가 끝났다면 최대 회의 개수는 1로 끝일까? 아니다. 

=> 5~5도 가능하기 때문에 최대 회의 개수는 2이다.

 

위의 코드에서는 회의의 끝 시간으로 오름차순 정렬했기 때문에 5~5 회의만 체크해서 1을 반환하게 된다.

 

즉, 시작 시간과 끝 시간이 같은 회의가 있다면 끝 시간으로 오름차순 정렬이 아니라 시작 시간으로 정렬해야 한다. 

 

정렬 조건을 다음과 같이 수정했다.

arr.sort {
    if $0[1] == $1[1]{
        return $0[0] < $1[0]
    } else {
        return $0[1] < $1[1]
    }
}

 


전체코드

 

let N = Int(readLine()!)!

var arr = [[Int]](repeating: [Int](repeating: 0, count: 2), count: N)

for i in 0..<N{
    let input = readLine()!.split(separator: " ").map{Int(String($0))!}
    
    arr[i][0] = input[0]
    arr[i][1] = input[1]
    
}

arr.sort {
    if $0[1] == $1[1]{
        return $0[0] < $1[0]
    } else {
        return $0[1] < $1[1]
    }
}

var current = 0
for i in 0..<N{
    let begin = arr[i][0]
    let end = arr[i][1]
    
    if current <= begin{
        current = end
        result += 1
    }else{
        continue
    }
}

print(result)

'백준 > 백준 - 스위프트' 카테고리의 다른 글

1012번: 유기농 배추  (0) 2023.12.07
1260번: DFS와 BFS  (0) 2023.12.06
1541번: 잃어버린 괄호  (0) 2023.11.22
1713번: 후보 추천하기  (0) 2023.11.15
11403번: 경로찾기  (0) 2023.11.13
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함