https://www.acmicpc.net/problem/2457
오늘은 공주님이 태어난 경사스러운 날이다. 왕은 이 날을 기념하기 위해 늘 꽃이 피어있는 작은 정원을 만들기로 결정했다.
총 N개의 꽃이 있는 데, 꽃은 모두 같은 해에 피어서 같은 해에 진다. 하나의 꽃은 피는 날과 지는 날이 정해져 있다. 예를 들어, 5월 8일 피어서 6월 13일 지는 꽃은 5월 8일부터 6월 12일까지는 꽃이 피어 있고, 6월 13일을 포함하여 이후로는 꽃을 볼 수 없다는 의미이다. (올해는 4, 6, 9, 11월은 30일까지 있고, 1, 3, 5, 7, 8, 10, 12월은 31일까지 있으며, 2월은 28일까지만 있다.)
이러한 N개의 꽃들 중에서 다음의 두 조건을 만족하는 꽃들을 선택하고 싶다.
N개의 꽃들 중에서 위의 두 조건을 만족하는, 즉 3월 1일부터 11월 30일까지 매일 꽃이 한 가지 이상 피어 있도록 꽃들을 선택할 때, 선택한 꽃들의 최소 개수를 출력하는 프로그램을 작성하시오.
첫째 줄에는 꽃들의 총 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 다음 N개의 줄에는 각 꽃이 피는 날짜와 지는 날짜가 주어진다. 하나의 날짜는 월과 일을 나타내는 두 숫자로 표현된다. 예를 들어서, 3 8 7 31은 꽃이 3월 8일에 피어서 7월 31일에 진다는 것을 나타낸다.
첫째 줄에 선택한 꽃들의 최소 개수를 출력한다. 만약 두 조건을 만족하는 꽃들을 선택할 수 없다면 0을 출력한다.
이번 문제는 그리디 알고리즘이다. 그런데 구현력까지 필요해 정말 오랜 시간 풀었던 문제이다. 문제 풀이를 바로 시작해보겠다.
문제는 3월1일부터 11월 30일까지 꽃이 하나 이상 피어있어야 한다. 그래서 초기값은
3월1일을 포함하여 이 전까지 핀 꽃 중에 제일 오래사는 꽃이 필요하다. 그리고 제일 오래사는 꽃을 찾게 된다면 그 꽃이 죽는 날을 기준으로 위 행동을 반복하면 된다.
여기서 해당 꽃이 11월 31일까지 살게 된다면 기록했던 꽃의 수를 반환을 하고 최종적으로 11월 31일까지 못갔다면 0을 반환하면 된다.
그리고 만약 꽃이 없는 기간이 생기게 되면 이 또한 바로 0을 반환하면 된다!
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class Main {
public static class Flower implements Comparable<Flower>{
int start, end;
public Flower(int start, int end) {
this.start = start;
this.end = end;
}
@Override
public int compareTo(Flower o) {
if(this.start == o.start){
return o.end - this.end;
}
return this.start - o.start;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
PriorityQueue<Flower> pq = new PriorityQueue<>();
int startValue = 31;
int endValue = 1130;
int answer = 0;
for(int i = 0; i < N ; i++){
StringTokenizer st = new StringTokenizer(br.readLine());
String str1 = st.nextToken();
String str2 = st.nextToken();
if(str2.length() == 1){
str2 = 0 + str2;
}
String str3 = st.nextToken();
String str4 = st.nextToken();
if(str4.length() == 1){
str4 = 0 + str4;
}
int start = Integer.parseInt(str1 + str2);
int end = Integer.parseInt(str3 + str4);
if(end <= startValue || start > endValue) continue;
pq.offer(new Flower(start, end));
}
if(pq.size() == 0){
System.out.println(0);
}
int value = 301;
while(!pq.isEmpty()){
int max = 0;
boolean check = false;
while(!pq.isEmpty()){
Flower flower = pq.peek();
if(value >= flower.start){
pq.poll();
check = true;
max = Math.max(max, flower.end);
}else{
break;
}
}
if(!check) break;
answer++;
value = max;
if(value > endValue) break;
}
if(value > endValue){
System.out.println(answer);
}else{
System.out.println(0);
}
}
}