Argorithm 이론

코테 유형 별 기출 선정하기

빙응이 2025. 5. 16. 00:06

📝DP

📌최장 증가 부분 수열(LIS)

11053번: 가장 긴 증가하는 부분 수열
더보기
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int a = Integer.parseInt(br.readLine());

        StringTokenizer st = new StringTokenizer(br.readLine());
        int dp[] = new int[a];
        int arr[] = new int[a];
        Arrays.fill(dp, 1);

        for(int i = 0; i < a; i++){
            arr[i] = Integer.parseInt(st.nextToken());
        }

        int max = 0;
        for(int i = 0; i < a; i++){
            for(int j = 0; j < i; j++){
                if(arr[i] > arr[j] && dp[i] < dp[j] + 1) dp[i] = dp[j] + 1;
            }

            max = Math.max(max, dp[i]);
        }
        System.out.println(max);
    }
}
12015번: 가장 긴 증가하는 부분 수열 2 
더보기
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int a = Integer.parseInt(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine());

        List<Integer> li = new ArrayList<>();
        for(int i = 0; i < a; i++){
            int cnt = Integer.parseInt(st.nextToken());

            int pos = Collections.binarySearch(li, cnt);

            if(pos < 0) pos = -(pos + 1);

            if(pos == li.size()){
                li.add(cnt);
            }else{
                li.set(pos, cnt);
            }
        }

        System.out.println(li.size());
    }
}

 

14002번: 가장 긴 증가하는 부분 수열 4
더보기
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int a = Integer.parseInt(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine());

        int arr[] = new int[a];

        for(int i = 0; i < a; i++){
            arr[i] = Integer.parseInt(st.nextToken());
        }

        int dp[] = new int[a]; // dp 배열
        int prev[] = new int[a]; // 가장 긴 증가하는 부분 수열 출력용

        Arrays.fill(dp, 1); //기본 1
        Arrays.fill(prev, -1);

        int max = 0;
        int index = 0;
        for(int i = 0; i < a; i++){
            for(int j = 0; j < i; j++){
                if(arr[i] > arr[j] && dp[i] < dp[j] + 1){
                    dp[i] = dp[j] + 1;
                    prev[i] = j;
                }
            }
            if(max < dp[i]){
                max = dp[i];
                index = i;
            }
        }
        StringBuilder sb = new StringBuilder();

        int cnt = index;
        while(cnt != -1){
            sb.insert(0, arr[cnt] + " ");
            cnt = prev[cnt];
        }
        System.out.println(max);
        System.out.println(sb);


    }
}
11054번: 가장 긴 바이토닉 부분 수열
더보기
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int a = Integer.parseInt(br.readLine());

        StringTokenizer st = new StringTokenizer(br.readLine());
        int up[] = new int[a];
        int down[] = new int[a];
        int arr[] = new int[a];
        Arrays.fill(up, 1);
        Arrays.fill(down, 1);

        for(int i = 0; i < a; i++){
            arr[i] = Integer.parseInt(st.nextToken());
        }


        for(int i = 1; i < a; i++){
            for(int j = 0; j < i; j++){
                if(arr[i] > arr[j] && up[i] < up[j] + 1){
                    up[i] = up[j] + 1;
                }
            }
        }

        for(int i = a - 2; i >= 0; i--){
            for(int j = a - 1; j > i; j--){
                if(arr[i] > arr[j] && down[i] < down[j] + 1){
                    down[i] = down[j] + 1;
                }
            }
        }

        int max = 0;
        for(int i = 0; i < a; i++){
            max = Math.max(max, up[i] + down[i] - 1);
        }

        System.out.println(max);
    }
}

📌 다차원 DP

17069번: 파이프 옮기기2
더보기
import java.io.*;
import java.util.*;

public class Main {
    static final int HORIZONTAL = 0;
    static final int VERTICAL = 1;
    static final int DIAGONAL = 2;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());

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

        long[][][] dp = new long[n][n][3];
        dp[0][1][HORIZONTAL] = 1;

        for (int i = 0; i < n; i++) {
            for (int j = 1; j < n; j++) {
                if (map[i][j] == 1) continue;

                if (j - 1 >= 0) {
                    dp[i][j][HORIZONTAL] += dp[i][j - 1][HORIZONTAL] + dp[i][j - 1][DIAGONAL];
                }
                if (i - 1 >= 0) {
                    dp[i][j][VERTICAL] += dp[i - 1][j][VERTICAL] + dp[i - 1][j][DIAGONAL];
                }

                if (i - 1 >= 0 && j - 1 >= 0) {
                    if (map[i - 1][j] == 0 && map[i][j - 1] == 0) {
                        dp[i][j][DIAGONAL] += dp[i - 1][j - 1][HORIZONTAL] +
                                              dp[i - 1][j - 1][VERTICAL] +
                                              dp[i - 1][j - 1][DIAGONAL];
                    }
                }
            }
        }

        long result = dp[n - 1][n - 1][HORIZONTAL] +
                      dp[n - 1][n - 1][VERTICAL] +
                      dp[n - 1][n - 1][DIAGONAL];

        System.out.println(result);
    }
}
10942번: 팰린드롬?
더보기
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());

        int arr[] = new int[n + 1];

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

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

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

        for(int i = 2; i <= n; i++){
            for(int j = 1; j <= n - i; j++){
                int x = j + i;
                if(arr[j] == arr[x] && dp[j + 1][x - 1] == 1)
                    dp[j][x] = 1;
            }
        }

        StringBuilder sb = new StringBuilder();
        int m = Integer.parseInt(br.readLine());
        for(int i = 0; i < m; i++){
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            sb.append(dp[a][b]).append("\n");
        }

        System.out.println(sb);        
    }
}
17404번: RGB 거리2
더보기
import java.io.*;
import java.util.*;

public class Main {
    static final int INF = 1_000_000_000;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());

        int[][] cost = new int[n + 1][3];
        for (int i = 1; i <= n; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            for (int j = 0; j < 3; j++) {
                cost[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        int[][][] dp = new int[n + 1][3][3]; 
        int result = INF;

        for (int start = 0; start < 3; start++) {
            for (int c = 0; c < 3; c++) {
                if (c == start) dp[1][c][start] = cost[1][c];
                else dp[1][c][start] = INF;
            }

            for (int i = 2; i <= n; i++) {
                dp[i][0][start] = Math.min(dp[i - 1][1][start], dp[i - 1][2][start]) + cost[i][0];
                dp[i][1][start] = Math.min(dp[i - 1][0][start], dp[i - 1][2][start]) + cost[i][1];
                dp[i][2][start] = Math.min(dp[i - 1][0][start], dp[i - 1][1][start]) + cost[i][2];
            }

            for (int end = 0; end < 3; end++) {
                if (end == start) continue;
                result = Math.min(result, dp[n][end][start]);
            }
        }

        System.out.println(result);
    }
}

 

📝BFS/DFS

📌BFS + 다익스트라

13549번: 숨바꼭질 3
더보기
import java.io.*;
import java.util.*;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());

        int[] dp = new int[100001];
        Arrays.fill(dp, Integer.MAX_VALUE);

        PriorityQueue<int[]> q = new PriorityQueue<>((a,b) -> a[1] - b[1]);

        q.add(new int[]{n, 0});
        dp[n] = 0;

        while (!q.isEmpty()) {
            int[] now = q.poll();
            int pos = now[0];
            int time = now[1];

            if (pos == m) {
                System.out.println(time);
                return;
            }

            // 순간이동 (0초)
            if (pos * 2 < 100001 && dp[pos * 2] > time) {
                dp[pos * 2] = time;
                q.add(new int[]{pos * 2, time});
            }

            // 뒤로 걷기 (1초)
            if (pos - 1 >= 0 && dp[pos - 1] > time + 1) {
                dp[pos - 1] = time + 1;
                q.add(new int[]{pos - 1, time + 1});
            }

            // 앞으로 걷기 (1초)
            if (pos + 1 < 100001 && dp[pos + 1] > time + 1) {
                dp[pos + 1] = time + 1;
                q.add(new int[]{pos + 1, time + 1});
            }
        }
    }
}
13913번: 숨바꼭질4
더보기
import java.io.*;
import java.util.*;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());

        int[] dp = new int[100001];
        int[] prev = new int[100001];
        Arrays.fill(dp, Integer.MAX_VALUE);
        Arrays.fill(prev, -1);
        PriorityQueue<int[]> q = new PriorityQueue<>((a,b) -> a[1] - b[1]);

        q.add(new int[]{n, 0});
        dp[n] = 0;

        while (!q.isEmpty()) {
            int[] now = q.poll();
            int pos = now[0];
            int time = now[1];

            if(dp[pos] < time) continue;

            if(pos == m) break;
            
            // 순간이동 (1초)
            if (pos * 2 < 100001 && dp[pos * 2] > time + 1) {
                dp[pos * 2] = time + 1;
                prev[pos * 2] = pos;
                q.add(new int[]{pos * 2, time + 1});
            }

            // 앞으로 걷기 (1초)
            if (pos + 1 < 100001 && dp[pos + 1] > time + 1) {
                dp[pos + 1] = time + 1;
                prev[pos + 1] = pos;
                q.add(new int[]{pos + 1, time + 1});
            }
            // 뒤로 걷기 (1초)
            if (pos - 1 >= 0 && dp[pos - 1] > time + 1) {
                dp[pos - 1] = time + 1;
                prev[pos - 1] = pos;
                q.add(new int[]{pos - 1, time + 1});
            }
        }

        System.out.println(dp[m]);
        StringBuilder sb = new StringBuilder();
        sb.append(m);
        int cnt = m;
        while(prev[cnt] != -1){
            sb.insert(0, prev[cnt] + " ");
            cnt = prev[cnt];
        }

        System.out.println(sb);
    }
}

📌DFS + 백트래킹

15649번: N과 M 1
더보기
import java.io.*;
import java.util.*;

public class Main {
    static StringBuilder sb = new StringBuilder();
    static int n,m;
    static int arr[];
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());
        arr = new int[m];
        boolean visited[] = new boolean[n + 1];
        dfs(0, visited);
        System.out.println(sb);
    }

    public static void dfs(int depth, boolean visited[]){
        if(depth == m){
            for(int i = 0; i < m; i++){
                sb.append(arr[i]).append(" ");
            }

            sb.append("\n");
            return;
        }

        for(int i = 1; i <= n; i++){
            if(!visited[i]){
                visited[i] = true;
                arr[depth] = i;
                dfs(depth + 1, visited);
                visited[i] = false;
            }
        }
    }
}
15650번 : N과 M 2
더보기
import java.io.*;
import java.util.*;

public class Main {
    static StringBuilder sb = new StringBuilder();
    static int n,m;
    static int arr[];
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());
        arr = new int[m];
        dfs(0, 1);
        System.out.println(sb);
    }

    public static void dfs(int depth, int start){
        if(depth == m){
            for(int i = 0; i < m; i++){
                sb.append(arr[i]).append(" ");
            }

            sb.append("\n");
            return;
        }

        for(int i = start; i <= n; i++){
            arr[depth] = i;
            dfs(depth + 1, i + 1);
        }
    }
}
15651번 : N과 M 3
더보기
import java.io.*;
import java.util.*;

public class Main {
    static StringBuilder sb = new StringBuilder();
    static int n,m;
    static int arr[];
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());
        arr = new int[m];
        dfs(0);
        System.out.println(sb);
    }

    public static void dfs(int depth){
        if(depth == m){
            for(int i = 0; i < m; i++){
                sb.append(arr[i]).append(" ");
            }

            sb.append("\n");
            return;
        }

        for(int i = 1; i <= n; i++){
            arr[depth] = i;
            dfs(depth + 1);
        }
    }
}
14888번 : 연산자 끼워넣기
더보기
import java.io.*;
import java.util.*;

public class Main {
    static int n;
    static int arr[];
    static int m[];
    static int max = Integer.MIN_VALUE;
    static int min = Integer.MAX_VALUE;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        n = Integer.parseInt(br.readLine());

        arr = new int[n];
        m = new int[4];

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

        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < 4; i++) m[i] = Integer.parseInt(st.nextToken());

        dfs(1, arr[0]);

        System.out.println(max);
        System.out.println(min);
    }

    public static void dfs(int depth, int num) {
        if (depth == n) {
            max = Math.max(max, num);
            min = Math.min(min, num);
            return;
        }

        for (int i = 0; i < 4; i++) {
            if (m[i] > 0) {
                m[i]--;
                if (i == 0) dfs(depth + 1, num + arr[depth]);
                else if (i == 1) dfs(depth + 1, num - arr[depth]);
                else if (i == 2) dfs(depth + 1, num * arr[depth]);
                else {
                    int result;
                    if (num < 0)
                        result = -(-num / arr[depth]);
                    else
                        result = num / arr[depth];
                    dfs(depth + 1, result);
                }
                m[i]++;
            }
        }
    }
}

 

📝해시

📌해시 조합

9375번: 패션왕 신해빈
더보기
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int t = Integer.parseInt(br.readLine());

        while(t-- > 0){
            Map<String, HashSet<String>> m = new HashMap<>();
            int n = Integer.parseInt(br.readLine());

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

                m.computeIfAbsent(b, k -> new HashSet<>()).add(a);
            }
            int result = 1;
            for(HashSet<String> h : m.values()){
                result *= (h.size() + 1);
            }
            result -= 1;
            System.out.println(result);
        }

    }
}
7785번: 회사에 있는 사람
더보기
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        Map<String, Integer> m = new HashMap<>();

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

            if(b.equals("enter")){
                m.put(a, 0);
            }else{
                m.remove(a);
            }
        }

        List<String> names = new ArrayList<>(m.keySet());
        Collections.sort(names, Collections.reverseOrder());
        

        for (String name : names) {
            System.out.println(name);
        }
    }
}
5052번: 전화번호 목록
더보기
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int t = Integer.parseInt(br.readLine());

        while (t-- > 0) {
            int n = Integer.parseInt(br.readLine());
            Map<String, Boolean> map = new HashMap<>();
            String[] arr = new String[n];

            for (int i = 0; i < n; i++) {
                arr[i] = br.readLine();
            }

            for (String phone : arr) {
                map.put(phone, false);
            }

            boolean flag = false;

            for (String phone : arr) {
                for (int len = 1; len < phone.length(); len++) {
                    String prefix = phone.substring(0, len);
                    if (map.containsKey(prefix) && map.get(prefix) == false) {
                        flag = true;
                        break;
                    }
                }
                if (flag) break;
            }

            System.out.println(flag ? "NO" : "YES");
        }
    }
}

 

📝자료구조

📌스택

1918번 : 후위표기식
더보기
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        

        String target = br.readLine();
        Stack<Character> s = new Stack<>();

        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < target.length(); i++){
            char cnt = target.charAt(i);
            

            if(cnt == '('){
                s.push(cnt);
            }else if(cnt == ')'){
                while(!s.isEmpty() && s.peek() != '('){
                    sb.append(s.pop());
                }

                s.pop();
            }else if(cnt == '+' || cnt == '-'){
                if(!s.isEmpty() && (s.peek() == '*' || s.peek() == '/')){
                    sb.append(s.pop());
                }
                if(!s.isEmpty() && s.peek() != '('){
                    sb.append(s.pop());
                }
                s.push(cnt);
            }else if(cnt == '*' || cnt == '/'){
                if(!s.isEmpty() && (s.peek() == '*' || s.peek() == '/')){
                    sb.append(s.pop());
                }
                s.push(cnt);
            }else{
                sb.append(cnt);
            }
        }

        while(!s.isEmpty()){
            sb.append(s.pop());
        }
        System.out.println(sb);
    }

}

// 스택에 계산식을 넣는다.
// 만약 계산식이 x / 가 나온 후 - +가 나오면 x를 먼저 출력한다. 만약 가로가 나오면 가로 먼저 출력
// 만약 ( 가 나오면 다음 것은 일단 스택에 넣지 않고 출력을 한다.

계속 추가 예정