백준 BaekJoon 11000번: 강의실 배정 [Java] 자바

2020-11-12


문제

수강신청의 마스터 김종혜 선생님에게 새로운 과제가 주어졌다. 

김종혜 선생님한테는 Si에 시작해서 Ti에 끝나는 N개의 수업이 주어지는데, 최소의 강의실을 사용해서 모든 수업을 가능하게 해야 한다. 

 

참고로, 수업이 끝난 직후에 다음 수업을 시작할 수 있다. (즉, Ti ≤ Sj 일 경우 i 수업과 j 수업은 같이 들을 수 있다.)

수강신청 대충 한 게 찔리면, 선생님을 도와드리자!

입력

첫 번째 줄에 N이 주어진다. (1 ≤ N ≤ 200,000)

이후 N개의 줄에 Si, Ti가 주어진다. (1 ≤ Si < Ti ≤ 109)

출력

강의실의 개수를 출력하라.


풀이 

사실 처음에는 주어진 예제를 보고 강의 순서가 시간별 순서대로 나열된다고 생각하여, 접근하였다. 때문에 강의의 종료 시간과 다음 강의의 시작시간만 비교하면 될 거라고 생각했다. 하지만 이는 너무 단순하다고 생각했다.

 

문제를 자세히 보니 추가적으로 고려하여야 할 조건이 보였다. (물론 정답률이 낮아서 자세히 읽어보았다.)

강의 시간의 순서가 뒤죽박죽일 수 있다. ex)  1~3 보다 3~5 가 먼저 나올 수도 있다.

때문에 첫번째 강의 시작시간뿐 아니라 끝나는 시간도 같이 고려해야 한다.

 

풀이 방법은 두 가지를 이용하였다.

 

 

단순 배열 위치 비교 풀이

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class TemplateA {
		public static void main(String[] args)  {
			
			Scanner scan = new Scanner(System.in);
			int n = scan.nextInt();
			int [][] arr = new int [n][2];
			
			for(int i = 0; i < n ; i++) {
				for(int j = 0; j < 2; j++) {
					arr[i][j] = scan.nextInt();
				}
			}
			//2차월 배열 정렬 0번쨰 열 다음 1번째 열 기준(다중 배열 정렬)
			Arrays.sort(arr, new Comparator<int[]>() {
			    public int compare(int[] o1, int[] o2) {
			    	 if(o1[0] == o2[0]) {
		                   return o1[1] - o2[1];
			    	 }else {
			    		 return o1[0] - o2[0]; 
			    	 }
		           }
		        });
			
			int count = 1;
			//총 강의 가능 횟수
			int temp = 0;
			//강위 시작시간 저장 변수
			for(int i = 1; i < n; i++) {
				if(arr[temp][1] <= arr[i][0]) {
					count++;
					//처음 강의의 끝나는 시간보다 
					//다음 강의의 시작 시간 같거나 크면
					//강의 진행 가능
					temp = i;
					//시작시간 i번째 강의로 초기화 
				}
			}
		    
		
		
		}
	}




우선순위 Q를 이용한 풀이

import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;

public class TemplateA {
		public static void main(String[] args)  {
			
			Scanner scan = new Scanner(System.in);
			int n = scan.nextInt();
			int [][] arr = new int [n][2];
			
			for(int i = 0; i < n ; i++) {
				for(int j = 0; j < 2; j++) {
					arr[i][j] = scan.nextInt();
				}
			}
			//2차월 배열 정렬 0번쨰 열 다음 1번째 열 기준(다중 배열 정렬)
			Arrays.sort(arr, new Comparator<int[]>() {
			    public int compare(int[] o1, int[] o2) {
			    	 if(o1[0] == o2[0]) {
		                   return o1[1] - o2[1];
			    	 }else {
			    		 return o1[0] - o2[0]; 
			    	 }
		           }
		        });
			//
			
			PriorityQueue<Integer> pQ = new PriorityQueue<>();
			
			for(int i = 0; i < n; i++) {
                            int end = arr[i][1];
                            //i 번째 강의의 끝나는 시간 저장
                            if(!pQ.isEmpty() && pQ.peek() <= arr[i][0])
                                //큐가 비어있지 않고 && pQ의 첫번째 값이 배열의 
                                //i 번째 강의의 시작시간보다 같거나 작으면
                                pQ.poll();
                                //pQ의 값을 하나 제거
                            pQ.offer(end);
                            //if문이 실행되지 않을시 end값 저장
                        }
                        System.out.println(pQ.size());
                        //남은 큐 값을 출력하면 전체 진행가능한 강의 수가 나옴

		}
    }

 

출처링크:www.acmicpc.net/problem/11000

 

11000번: 강의실 배정

첫 번째 줄에 N이 주어진다. (1 ≤ N ≤ 200,000) 이후 N개의 줄에 Si, Ti가 주어진다. (1 ≤ Si < Ti ≤ 109)

www.acmicpc.net