관리 메뉴

Partially Committed

[λ°±μ€€ 18870/2565/2470/4195] μžλ°” λ³Έλ¬Έ

πŸ”₯ Algorithm || λ¬Έμ œν’€μ΄/PS

[λ°±μ€€ 18870/2565/2470/4195] μžλ°”

WonderJay 2023. 2. 17. 12:08
728x90
λ°˜μ‘ν˜•
SMALL

(title: [λ°±μ€€ 18770/2565/2470/4195] μžλ°”)

A. μ’Œν‘œμ••μΆ• BOJ 18870

https://www.acmicpc.net/problem/18870

 

18870번: μ’Œν‘œ μ••μΆ•

μˆ˜μ§μ„  μœ„μ— N개의 μ’Œν‘œ X1, X2, ..., XN이 μžˆλ‹€. 이 μ’Œν‘œμ— μ’Œν‘œ 압좕을 μ μš©ν•˜λ €κ³  ν•œλ‹€. Xiλ₯Ό μ’Œν‘œ μ••μΆ•ν•œ κ²°κ³Ό X'i의 값은 Xi > Xjλ₯Ό λ§Œμ‘±ν•˜λŠ” μ„œλ‘œ λ‹€λ₯Έ μ’Œν‘œμ˜ κ°œμˆ˜μ™€ κ°™μ•„μ•Ό ν•œλ‹€. X1, X2, ..., XN에 쒌

www.acmicpc.net

λ‚œμ΄λ„ Silver 2
풀이 μ‹œκ°„ 10 λΆ„
λΆ„λ₯˜ μ •λ ¬, Hash map
μ‹œκ°„λ³΅μž‘λ„ 1. μž…λ ₯으둜 μ£Όμ–΄μ§€λŠ” n 개의 숫자λ₯Ό 배열에 μ €μž₯ν•˜λŠ” λΆ€λΆ„ O(n)
2. μˆœμœ„ 할당을 μœ„ν•œ temp 배열을 μ •λ ¬ν•˜λŠ” λΆ€λΆ„ O(nlogn)
3. hash map 에 temp λ°°μ—΄μ˜ μš”μ†Œλ₯Ό μΆ”κ°€ν•˜λ©΄μ„œ μ€‘λ³΅λœ 값을 κ±ΈλŸ¬λ‚΄λŠ” 뢀뢄은 temp 배열을 μ²˜μŒλΆ€ν„°
λκΉŒμ§€ μˆœμ°¨νƒμƒ‰ν•˜λ―€λ‘œ O(n)
β–Ά O(n+nlogn+n) ~= O(nlogn) 
κ³΅κ°„λ³΅μž‘λ„ 1. arr λ°°μ—΄ O(n)
2. temp λ°°μ—΄ O(n)
3. hash map O(n)
β–Ά O(n+n+n) ~= O(n)

import java.io.*;
import java.util.*;


public class Main {

    public static void main(String[] args) throws IOException {
        System.setIn(new FileInputStream("src/input.txt"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer stk;

        int n = Integer.parseInt(br.readLine());
        Map<Integer, Integer> hm = new HashMap<>();
        int [] arr = new int[n];
        Integer [] temp = new Integer[n];
        stk = new StringTokenizer(br.readLine());
        for(int i = 0 ; i < n ; i++){
            arr[i] = Integer.parseInt(stk.nextToken());
            temp[i] = arr[i];
        }

        Arrays.sort(temp); int rank = 0;
        for(int i = 0; i < n; i++){
            if(hm.containsKey(temp[i])){
                continue;
            } else {
                hm.put(temp[i], rank++);
            }
        }
        for(int i = 0 ; i < n ; i++){
            bw.write(hm.get(arr[i])+" ");
        } bw.write("\n");


        bw.flush();
        bw.close();
    }
}

 

B. μ „깃쀄 BOJ 2565

https://www.acmicpc.net/problem/2565

 

2565번: 전깃쀄

첫째 μ€„μ—λŠ” 두 μ „λ΄‡λŒ€ μ‚¬μ΄μ˜ μ „κΉƒμ€„μ˜ κ°œμˆ˜κ°€ 주어진닀. μ „κΉƒμ€„μ˜ κ°œμˆ˜λŠ” 100 μ΄ν•˜μ˜ μžμ—°μˆ˜μ΄λ‹€. λ‘˜μ§Έ 쀄뢀터 ν•œ 쀄에 ν•˜λ‚˜μ”© 전깃쀄이 Aμ „λ΄‡λŒ€μ™€ μ—°κ²°λ˜λŠ” μœ„μΉ˜μ˜ λ²ˆν˜Έμ™€ Bμ „λ΄‡λŒ€μ™€ μ—°κ²°λ˜λŠ”

www.acmicpc.net

λ‚œμ΄λ„ Gold 5
풀이 μ‹œκ°„ 30 λΆ„
λΆ„λ₯˜ LIS, DP
μ‹œκ°„λ³΅μž‘λ„ O(n^2) ; n <= 100 이라 κ°€λŠ₯
n 이 크닀면, binary search λ₯Ό μ΄μš©ν•œ nlogn LIS 풀이λ₯Ό μ‚¬μš©ν•΄μ•Ό 함.
κ³΅κ°„λ³΅μž‘λ„ O(n)
import java.io.*;
import java.util.*;


public class Main {
    static int n;
    static ArrayList<link> arr;
    static class link implements Comparable<link>{
        int left;
        int right;

        public link(int left, int right) {
            this.left = left;
            this.right = right;
        }

        @Override
        public int compareTo(link o) {
            if(this.left > o.left)
                return 1;
            else return -1;
        }
    }

    public static void main(String[] args) throws IOException {
        System.setIn(new FileInputStream("src/input.txt"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer stk;

        n = Integer.parseInt(br.readLine());
        arr = new ArrayList<>();
        for(int i = 0 ; i < n; i++){
            stk = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(stk.nextToken());
            int b = Integer.parseInt(stk.nextToken());
            arr.add(new link(a, b));
        }
        int [] dp = new int[n];

        for(int i = 0 ; i < n; i++){
            dp[i] = 1;
        }

        Collections.sort(arr);

        int max = -1;
        for(int i = 0; i <n; i++){
            for(int j = 0 ; j < i ; j++){
                if(arr.get(j).right < arr.get(i).right){
                    dp[i] = Math.max(dp[i], dp[j]+1);
                    max = Math.max(max, dp[i]);
                }
            }
        }

        int ans = n-max;
        bw.write(ans+"\n");


        bw.flush();
        bw.close();
    }
}

 

C. λ‘ μš©μ•‘ BOJ 2470

https://www.acmicpc.net/problem/2470

 

2470번: 두 μš©μ•‘

첫째 μ€„μ—λŠ” 전체 μš©μ•‘μ˜ 수 N이 μž…λ ₯λœλ‹€. N은 2 이상 100,000 μ΄ν•˜μ΄λ‹€. λ‘˜μ§Έ μ€„μ—λŠ” μš©μ•‘μ˜ νŠΉμ„±κ°’μ„ λ‚˜νƒ€λ‚΄λŠ” N개의 μ •μˆ˜κ°€ λΉˆμΉΈμ„ 사이에 두고 주어진닀. 이 μˆ˜λ“€μ€ λͺ¨λ‘ -1,000,000,000 이상 1,000,00

www.acmicpc.net

λ‚œμ΄λ„ Gold 5
풀이 μ‹œκ°„ 45λΆ„
λΆ„λ₯˜ 투 포인터
μ‹œκ°„λ³΅μž‘λ„ O(nlogn)
κ³΅κ°„λ³΅μž‘λ„ O(n)
import java.io.*;
import java.util.*;


public class Main {

    public static void main(String[] args) throws IOException {
        System.setIn(new FileInputStream("src/input.txt"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer stk;

        int n = Integer.parseInt(br.readLine());

        int[] arr = new int[n];
        int[] ans = new int[2];

        stk = new StringTokenizer(br.readLine());
        for (int i = 0; i < n; i++) {
            arr[i] = Integer.parseInt(stk.nextToken());
        }

        Arrays.sort(arr); // nlogn

        int left = 0;
        int right = n - 1;
        int val = Integer.MAX_VALUE;
        int t = 0;
        while (left < right) {
            t = Math.abs(arr[left]+arr[right]);
            if(t<val){
                val = t;
                ans[0] = arr[left];
                ans[1] = arr[right];
            }
            if(arr[left]+arr[right]<0){
                left++;
            } else {
                right--;
            }
        }

        bw.write(ans[0]+" "+ans[1]+"\n");
        bw.flush();
        bw.close();
    }
}

 

 

D. μΉœκ΅¬ λ„€νŠΈμ›Œν¬ BOJ 4195

이 λ¬Έμ œλŠ” κΈ°μ–΅ν•΄λ‘˜λ§Œν•œ ν¬μΈνŠΈκ°€ μžˆλ‹€κ³  μƒκ°ν•΄μ„œ μ•„λž˜μ— μƒμ„Έν•˜κ²Œ μ„€λͺ…을 μΆ”κ°€ν•˜μ˜€λ‹€!

https://www.acmicpc.net/problem/4195

 

4195번: 친ꡬ λ„€νŠΈμ›Œν¬

첫째 쀄에 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ˜ κ°œμˆ˜κ°€ 주어진닀. 각 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ˜ 첫째 μ€„μ—λŠ” 친ꡬ κ΄€κ³„μ˜ 수 Fκ°€ 주어지며, 이 값은 100,000을 λ„˜μ§€ μ•ŠλŠ”λ‹€. λ‹€μŒ F개의 μ€„μ—λŠ” 친ꡬ 관계가 생긴 μˆœμ„œλŒ€λ‘œ 주어진

www.acmicpc.net

λ‚œμ΄λ„ Gold 2
풀이 μ‹œκ°„ 50 λΆ„
λΆ„λ₯˜ μœ λ‹ˆμ˜¨ νŒŒμΈλ“œ(Union-Find)
μ‹œκ°„λ³΅μž‘λ„ O(N)
κ³΅κ°„λ³΅μž‘λ„ O(N)

β–Ά union-find λ₯Ό 살짝 μ‘μš©ν•˜λŠ” λ¬Έμ œμ΄λ‹€. λ‹€λ§Œ, union 을 ν•  λ•Œλ§ˆλ‹€ ν•΄λ‹Ή μ§‘ν•©μ˜ 크기λ₯Ό 좜λ ₯ν•΄μ•Ό ν•˜λŠ”λ° μ²˜μŒμ—λŠ” λ‹¨μˆœν•˜κ²Œ μƒκ°ν•΄μ„œ μ‹œκ°„μ΄ˆκ³Όλ₯Ό λ°›μ•˜λ‹€. 😒

 

 

μ²˜μŒμ— μƒκ°ν•œ 방법은 μ•„λž˜μ™€ κ°™λ‹€.

 

β–Ά union(a, b) λ₯Ό ν•œλ‹€λ©΄, a 와 b λ₯Ό 일단 ν•©μΉ˜κ³ , parent 배열을 ν˜„μž¬ λ“±λ‘λœ 친ꡬ 개수만큼 μˆœνšŒν•˜λ©΄μ„œ a 와 같은 쑰상을 가지고 μžˆλŠ”μ§€ ( find(a) == find(iter)? ) 개수λ₯Ό μ„Έμ–΄μ£ΌλŠ” 방식을 νƒν•˜μ˜€λ‹€. ν•˜μ§€λ§Œ μ΄λ ‡κ²Œ ν•˜λ©΄ λŒ€μΆ© O(N) 번의 연산이 더 ν•„μš”ν•˜κΈ° λ•Œλ¬Έμ— κ²°κ΅­ O(N^2) 의 μ‹œκ°„λ³΅μž‘λ„λ₯Ό κ°€μ§€κ²Œ λ˜μ–΄ μ‹œκ°„ μ΄ˆκ³Όκ°€ λ°œμƒν•œλ‹€.

β–Ά 즉, νŠΉμ • μ›μ†Œκ°€ 주어지면 ν•΄λ‹Ή μ›μ†Œκ°€ μ†ν•œ μ§‘ν•©μ˜ 크기λ₯Ό κ΅¬ν•˜λŠ” 방법을 보닀 효율적으둜 κ°œμ„ ν•΄μ•Ό ν•œλ‹€. 

 

 

 

κ°œμ„ ν•œ 방법은 λ‹€μŒκ³Ό κ°™λ‹€.

 

β–Ά μ–΄μ°¨ν”Ό, μ›μ†Œκ°€ μ†ν•œ μ§‘ν•©μ˜ ν¬κΈ°λŠ” Union 을 ν•  λ•Œμ—λ§Œ λ³€ν•˜λŠ” 게 λ§žλ‹€.

β–Ά 그러면 각각의 μ›μ†Œκ°€ μ†ν•œ μ§‘ν•©μ˜ μ‚¬μ΄μ¦ˆλ₯Ό μ €μž₯ν•  배열을 λ”°λ‘œ μ„ μ–Έν•œ λ‹€μŒμ—, union 연산이 λ°œμƒν•  λ•Œ size 배열을 update ν•΄μ£Όλ©΄ λ˜μ§€ μ•Šμ„κΉŒ?

β–Ά κ·Έλ ‡κ²Œ ν•΄μ£Όλ©΄, a λΌλŠ” μ›μ†Œκ°€ μ†ν•œ μ§‘ν•©μ˜ μ‚¬μ΄μ¦ˆλ₯Ό κ΅¬ν•˜λŠ” 것은 κ·Έλƒ₯ size[find(a)] λ₯Ό κΊΌλ‚΄μ£Όλ©΄ λ˜λ―€λ‘œ λŒ€λž΅ O(1) 에 해결이 κ°€λŠ₯ν•˜λ‹€.

 

 

 

size 배열에 λŒ€ν•΄μ„œ 쑰금 더 μžμ„Έν•˜κ²Œ μ„€λͺ…ν•˜λ©΄ μ•„λž˜μ™€ κ°™λ‹€.

 

β–Ά μ΄ˆκΈ°μ— size λ₯Ό λͺ¨λ‘ 1 둜 μ΄ˆκΈ°ν™”ν•œλ‹€. μ™œλƒλ©΄ μ²˜μŒμ—λŠ” λ‹€λ“€ μΉœκ΅¬κ°€ 자기 μžμ‹ λ°–μ— μ—†μœΌλ‹ˆκΉŒ! (초기 μ§‘ν•©μ˜ μ›μ†ŒλŠ” 였직 자기 μžμ‹  뿐)

β–Ά union (a, b) λΌλŠ” 연산이 λ°œμƒν–ˆλ‹€κ³  κ°€μ •ν•΄λ³΄μž. λŒ€μΆ© λŸ¬ν”„ν•˜κ²Œ μƒκ°ν•΄μ„œ b λΌλŠ” 집합을 a 집합에 합쳐야 ν•œλ‹€λŠ” μƒν™©μœΌλ‘œ 이해해보면, size[b] λ₯Ό size[a] 에 μΆ•μ μ‹œν‚€λ©΄ 될 것 μž„μ„ 깨달을 수 μžˆλ‹€. κ·ΈλŸ¬λ‹ˆκΉŒ μ•„λž˜μ™€ 같이 union 연산을 μˆ˜μ •ν•΄μ£Όμž.

private static void union(int a, int b) {
    a = find(a);
    b = find(b);
    if (a != b) {
        if (a < b) {
            parent[b] = a;
            size[a] += size[b];
        } else {
            parent[a] = b;
            size[b] += size[a];
        }
    }
}

이와 같이 ν•΄μ£Όλ©΄ size 배열은 각각의 μ›μ†Œκ°€ 속해 μžˆλŠ” μ§‘ν•©μ˜ 크기λ₯Ό μ €μž₯ν•˜κ²Œ λœλ‹€. 이와 같은 κ³Όμ •μœΌλ‘œ, νŠΉμ • μ›μ†Œκ°€ μ†ν•œ μ§‘ν•©μ˜ μ‚¬μ΄μ¦ˆλ₯Ό κ΅¬ν•˜λŠ” 과정을 O(N) μ—μ„œ O(1) 둜 μ΅œμ ν™”ν•  수 있고, 그러면 μ΅œμ’…μ μΈ μ‹œκ°„ λ³΅μž‘λ„κ°€ λŒ€λž΅ O(N) 이 되기 λ•Œλ¬Έμ— 문제λ₯Ό ν•΄κ²°ν•  수 μžˆλ‹€!

 

 

 

전체 μ½”λ“œλŠ” μ•„λž˜μ™€ κ°™λ‹€. 

 

 

import java.io.*;
import java.util.*;


public class Main {
    static int id = 1;
    static Map<String, Integer> hm = new HashMap<>();
    static int[] parent;
    static int[] size;

    public static void main(String[] args) throws IOException {
        System.setIn(new FileInputStream("src/input.txt"));
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer stk;

        int tc = Integer.parseInt(br.readLine()); // ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€
        while (tc > 0) {
            tc--;
            int f = Integer.parseInt(br.readLine()); // 친ꡬ κ΄€κ³„μ˜ 수

            size = new int[f * 2 + 1];
            parent = new int[f * 2 + 1];
            for (int i = 1; i <= f * 2; i++) {
                parent[i] = i;
                size[i] = 1;
            }

            for (int i = 0; i < f; i++) {
                stk = new StringTokenizer(br.readLine());
                String a = stk.nextToken();
                String b = stk.nextToken();

                edit(a);
                edit(b);

                int aidx = hm.get(a);
                int bidx = hm.get(b);
                if(aidx!=bidx)
                    union(aidx, bidx);
                bw.write(size[find(aidx)]+"\n");
            }
        }
        bw.flush();
        bw.close();
    }

    private static void union(int a, int b) {
        a = find(a);
        b = find(b);
        if (a != b) {
            if (a < b) {
                parent[b] = a;
                size[a] += size[b];
            } else {
                parent[a] = b;
                size[b] += size[a];
            }
        }
    }

    private static int find(int a) {
        if (a == parent[a])
            return a;
        else return parent[a] = find(parent[a]);
    }

    private static void edit(String name) {
        if (hm.containsKey(name)) {
            hm.get(name);
        } else {
            hm.put(name, id++);
        }
    }
}

 

 

 

 

 

728x90
λ°˜μ‘ν˜•
LIST
Comments