Notice
Recent Posts
Recent Comments
Link
«   2025/09   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
관리 메뉴

전공공부

[BOJ_20442] ㅋㅋ루ㅋㅋ 본문

Study/Problem Solving

[BOJ_20442] ㅋㅋ루ㅋㅋ

monitor 2024. 1. 7. 13:23

설명


 

 R로만 이루어진 문자열은 ㅋㅋ루ㅋㅋ 문자열이다. 단, 빈 문자열은 ㅋㅋ루ㅋㅋ 문자열이 아니다.
 ㅋㅋ루ㅋㅋ 문자열 양 끝에 K를 하나씩 붙인 문자열은 ㅋㅋ루ㅋㅋ 문자열이다.
 
 부분 수열으로 더해지는 것을 생각을 하고 풀어야 이해가 되는 문제다. 처음 이해 자체가 되지 않아서 무슨 문제인지 파악하는 것이 어려웠다.
 

KKK RKRRKRKRKRKR KK 일때, K 갯수가 2이고 여기서 중간의 R은 제외되어서 보여야 한다.

 

그래서, 이렇게 나누어진 것을 보면 최소 K 2*2 + 중간에 존재하는 R의 갯수 7개를 더하면 값이 나오는데 이런 방식을 투포인터로 반복하면서 나가면서 최댓값을 구하는 것을 코드로 구현하면된다.

 

다음에는 KK가 최소 값이 나왔으니 r을 줄여서 다음 KRKK 까지 탐색하여 한 번 더 체크하면 될 것이다.

코드


 

package two_pointer;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * 조건
 * R로만 이루어진 문자열은 ㅋㅋ루ㅋㅋ 문자열이다. 단, 빈 문자열은 ㅋㅋ루ㅋㅋ 문자열이 아니다.
 * ㅋㅋ루ㅋㅋ 문자열 양 끝에 K를 하나씩 붙인 문자열은 ㅋㅋ루ㅋㅋ 문자열이다.
 *
 * 부분 수열으로 더해지는 것을 생각을 하고 풀어야 이해가 되는 문제다. 처음 이해 자체가 되지 않아서 무슨 문제인지 파악하는 것이 어려웠다.
 *
 * 'R' KK 'R' KKKK 'R' KKK 'R' KKK
 * (right - left + 1) 가운데 있는 R의 갯수가 맞다.
 *  - R의 갯수는 이미 지나쳐 온 오른쪽 k 사이즈에서 그 만큼 left 사이즈 만큼 뺀 것이다. 왜냐하면 R의 갯수가 나온 만큼 K 갯수를 넣었으니깐
 *  - 그리고 나의 R 갯수 하나를 더한다.
 * KKKRKK 일 경우 KK 최소 값이 먼저 선택이 되고 이때 선택된 값이 R을 선택해서 같은 값으로 간다
 * KKK RKRRKRKRKR KRKK 일때, K 갯수가 3이고 여기서 중간의 R은 제외되어서 보여야 한다.
 *
 *
 * */

public class BOJ_20442 {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String input = br.readLine();
        int max = solved(input);
        System.out.println(max); // 양쪽 끝의 K가 각각 한 번씩 포함됨
    }

    private static int solved(String input) {
        int length = input.length();
        List<Integer> lK = new ArrayList<>();
        List<Integer> rK = new ArrayList<>();
        int lc = 0;
        for(int i = 0; i < length; i++){
            if(input.charAt(i) == 'R'){
                lK.add(lc);
            }
            else{
                lc++;
            }
        }
        int rc = 0;
        for(int i = length - 1; i >= 0; i--){
            if(input.charAt(i) == 'R'){
                rK.add(rc);
            }
            else{
                rc++;
            }
        }
        reverseOrder(rK);
        int left = 0;
        int right = rK.size() - 1;
        int max = 0;
        while(left <= right){

            int padding = Math.min(lK.get(left),rK.get(right)) * 2;
            max = Math.max(padding + (right - left + 1), max);
            if(lK.get(left) > rK.get(right)){
                right--;
            }else{
                left++;
            }
        }
        return max;
    }
    private static void reverseOrder(List<Integer> list){
        Stack<Integer> st = new Stack<>();
        for (int c : list){
            st.push(c);
        }
        list.clear();
        while (!st.isEmpty()){
            list.add(st.pop());
        }
    }
}

 

 

20442번: ㅋㅋ루ㅋㅋ

어떤 문자열에서 몇 개의 문자를 지워서 부분 수열을 만들 수 있다. 예를 들어, ABC의 부분 수열은 ABC, AB, BC, AC, A, B, C와 빈 문자열이다.

www.acmicpc.net

 

'Study > Problem Solving' 카테고리의 다른 글

[BOJ_16398] 행성 연결  (0) 2024.01.10
[BOJ_1647] 도시 분할 계획  (0) 2024.01.08
[BOJ_20366] 같이 눈사람 만들래?  (0) 2024.01.06
[BOJ_1325] 효율적인 해킹  (2) 2024.01.05
[BOJ_16918] 봄버맨  (2) 2024.01.05