코딩테스트/인프런

인프런 JAVA 알고리즘 정리(Greedy Algorithm 1~8번)

고구마는호박고구마 2023. 5. 14. 19:34

1. 씨름 선수

키 몸무게가 있고 자신보다 키 몸무게 둘다 큰 사람이 없다면 선택

-> (183, 65) - 키가 제일 큼

-> (180, 70) - 자신보다 키가 큰 사람중 자신보다 몸무게 큰 사람이 없음

-> (170, 72) - 자신보다 키가 큰 사람중 자신보다 몸무게 큰 사람이 없음

 

1. 사람을 키순으로 정렬한다. ( 첫번째 사람은 일단 키가 제일 크니 픽)

2. 그 뒤로 몸무게가 앞 사람보다 크다면 픽 ( 앞사람보다 키는 작지만 몸무게는 제일 높다는 소리) 

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int num = sc.nextInt();
    ArrayList<Body> arr = new ArrayList<>();
    for(int i=0; i<num; i++){
        int h = sc.nextInt();
        int w = sc.nextInt();
        arr.add(new Body(h,w));
    }
    Collections.sort(arr);
    int cnt = 1;
    int weight  = arr.get(0).weight;
    // 몸무게가 앞에 나온 최고 몸무게 보다 크다면 선발
    for(int i=1; i<arr.size(); i++){
        if(weight<arr.get(i).weight){
            cnt++;
            weight=arr.get(i).weight;
        }
    }
    System.out.println(cnt);
}
// 사람 클래스를 키를 기준으로 내림차순 만든다.
static class Body implements Comparable<Body>{
    int key;
    int weight;
    public Body(int key, int weight){
        this.key = key;
        this.weight = weight;
    }
    @Override
    public int compareTo(Body o) {
        return o.key-this.key;
    }
}

 

 

 

2. 회의실 배정

// 끝나는 시간을 기준으로 오름 차순 정렬 -> 빨리 끝나는거를 찾기 위해

// 끝나는 시간이 같다면? -> 시작시간을 기준으로 오름 차순

public static int solution(ArrayList<Time> arr){
    int cnt =0;
    int et = 0;
    for(Time ob : arr) {
        // 끝나는 시간 보다 시작이간이 크거나 같으면 배정
        if(ob.s >= et){
            cnt++;
            et = ob.e;
        }
    }
    return cnt;
}
public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int num = sc.nextInt();
    ArrayList<Time> arr = new ArrayList<>();
    for(int i=0; i<num; i++){
        int s = sc.nextInt();
        int e = sc.nextInt();
        arr.add(new Time(s,e));
    }
    Collections.sort(arr);
    int result = solution(arr);
    System.out.println(result);

}


static class Time implements Comparable<Time>{
    int s;
    int e;
    public  Time(int s, int e){
        this.s = s;
        this.e = e;
    }
    // 끝나는 시간이 같다면 시작시간을 기준으로 오름차순 
    @Override
    public int compareTo(Time o) {
        if(this.e==o.e) return this.s - o.s;
        return this.e-o.e;
    }
}

 

 

 

3. 결혼식 

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int num = sc.nextInt();
    int[] day = new int[73];

    for(int i=0; i<num; i++){
        int s = sc.nextInt();
        int e = sc.nextInt();
        for(int j=s; j<e; j++)
            day[j]++;
    }
    int max = 0;
    for(int x : day) {
        if(x>max) max = x;
    }
    System.out.println(max);
    
}

 

4. 최대 수입 스케쥴(PriorityQueue 응용문제)

 

우선순위 큐 란? ( Logn )

-최소값이 기본으로 우선순위. -> poll() 가장 작은 값 리턴-최대값으로 우선순위를 한다면 reverse 해줘야 됨. -> poll() 가장 작은 큰 값 리턴

PriorityQueue<Integer> pQ = new PriorityQueue<>(Collections.reverseOrder());

 

- 1. 돈, 날짜 중 날짜를 내림차순으로 먼저 정렬

- 2. 날짜순으로 for문을 돌며 날짜들 중 최대 강연료를 GET

static int num, max = Integer.MIN_VALUE;
public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    num = sc.nextInt();
    ArrayList<Lecture> arr = new ArrayList<>();

    for(int i=0; i<num; i++){
        int m = sc.nextInt();
        int d = sc.nextInt();
        arr.add(new Lecture(m, d));
        if(d>max) max=d;
    }
    System.out.println(solution(arr));

}

public static int solution(ArrayList<Lecture> arr){
    int answer = 0;
    // 정수가 들어갔을 때 poll() 시 가장 큰값이 리턴
    PriorityQueue<Integer> pQ = new PriorityQueue<>(Collections.reverseOrder());
    Collections.sort(arr); // 날짜에 의해 내림차순 
    int j=0; // 순서대로 접근하기 위해 j값을 for문 밖 초기화
    for(int i=max; i>=1; i--){
        for(; j<num; j++){
            if(arr.get(j).time<i) break;
            pQ.offer(arr.get(j).money);
        }
        if(!pQ.isEmpty()) answer+=pQ.poll(); // 가장 높은 강연료 GET
    }
    return answer;
}
public static class Lecture implements Comparable<Lecture>{
    int money;
    int time;
    public Lecture(int money, int time){
        this.money = money;
        this.time = time;
    }

    @Override
    public int compareTo(Lecture o) {
        return o.time-this.time;
    }
}

 

 

5. 다익스트라 알고리즘

정점으로의 최소 거리비용을 출력하는 프로그램 

    

 

6. 친구인가? ( Union & Find )

서로소 집합을 만들어라. -> Union & Find 알고리즘

Union -> 한 집합으로 만드는 메서드 

 

 

7. 원더랜드(최소스패닝트리 : 크루스칼)

모든 도시를 최소 비용으로 연결해라.

1. PriorityQueue를 사용하여 최소 비용을 계속 출력 

2. UNION & FIND 알고리즘으로 같은 집합이면(그래프) -> 연결 금지 

3. 같은 집합이 아니면(no그래프) sum에 비용추가

public static int  find (int a){
    if(arr[a]==a) return arr[a];
    else return arr[a] = find(arr[a]);

}
public static boolean  union (int start, int end){
    int a = find(start);
    int b = find(end);
    if(a!=b) {
        arr[a] = b;
        return true;
    }else{
        return false;
    }
}
int sum = 0;
while(!pQ.isEmpty()){
    Route route = pQ.poll();
    if(union(route.start, route.end)) sum += route.value;
}

 

7. 원더랜드(최소스패닝트리 : 프림)

0. 각 정점을 인접리스트로 설정

1. PriorityQueue 활용

2. ch배열 설정후 작은비용이면 체크 -> 체크된 배열은 패스