ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준/JAVA] 21314번: 민겸 수
    Algorithm 2024. 7. 19. 09:38

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

     

    - 정답 코드

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    // 민겸 수가 십진수로 변환되었을 때 가질 수 있는 최댓값과 최솟값
    public class Main {
        public static void main(String[] args) throws IOException{
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String mg = br.readLine(); // MKM 
    
            StringBuilder max = new StringBuilder(); // 최대값
            StringBuilder min = new StringBuilder(); // 최소값
    
            int cntM = 0; // 연속된 M의 개수
    
            for(int i = 0; i < mg.length(); i++) {
                char currentChar = mg.charAt(i); // M
    
                if(currentChar == 'M') {
                    cntM++; // 1
                }else if(currentChar == 'K') {
    
                    // 1. 최대값 나오게
                    // 501 최대
                    // => MK + M 
                    if(cntM > 0) { // MK
                        max.append('5'); 
                        for(int j = 0; j < cntM; j++) {
                            max.append('0'); //  M의 개수만큼 0을 추가
                        }
                    }else{ // K
                        max.append('5');
                    }
    
                    // 2. 최솟값 나오게
                    // 151 최소
                    // => M + K + M
                    if(cntM > 0) { // MK
                        min.append('1'); // M을 1로 변환
                        for(int j = 1; j < cntM; j++) {
                            min.append('0'); // 나머지 M은 0으로
                        }
                        min.append('5'); // 현재 K를 5로 변환
                    }else{
                        min.append('5'); 
                    }
    
                    cntM = 0;
    
                }
            }
    
            // 남은 M 처리
            if(cntM > 0) {
                // 최대값
                for(int j = 0; j < cntM; j++) {
                    max.append('1');  // 남은 M 모두 1로 변환
                }
                // 최솟값
                min.append('1');
                for(int j = 1; j < cntM; j++) {
                    min.append('0'); 
                }
            }
    
            System.out.println(max);
            System.out.println(min);
        
        }
    }

    - 문제 풀이 ( 예제 입력: "MKM")

     

    1. 최댓값과 최솟값을 저장할 변수 및 연속된 'M'의 개수를 세기 위한 변수를 초기화

        public static void main(String[] args) throws IOException{
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String mg = br.readLine(); // MKM 
    
            StringBuilder max = new StringBuilder(); // 최대값
            StringBuilder min = new StringBuilder(); // 최소값
    
            int cntM = 0; // 연속된 M의 개수

     

     

    2. 입력 문자열을 순회하면서 'M'과 'K'를 처리

    for(int i = 0; i < mg.length(); i++) {
                char currentChar = mg.charAt(i); // M
    
                // 현재 문자가 'M'이면 cntM을 1 증가
                if(currentChar == 'M') {
                    cntM++; // 1
                    
                // 현재 문자가 'K'이면 최댓값과 최솟값을 계산
                }else if(currentChar == 'K') {

     

    • 입력 문자열 mg의 각 문자를 순회합니다.
    • 1. 현재 문자가 'M'이면 cntM을 1 증가시킵니다.
    • 2. 현재 문자가 'K'이면 최댓값과 최솟값을 계산합니다.

     

    3. 'K'를 만났을 때 최댓값과 최솟값 계산

    'K'를 만났을 때 현재까지의 'M'의 개수를 이용하여 최댓값과 최솟값을 계산

    문제 예시 참고

    // 1. 최대값 나오게
                    // 501 최대
                    // => MK + M 
                    if(cntM > 0) { // MK
                        max.append('5'); 
                        for(int j = 0; j < cntM; j++) { //  M의 개수만큼
                            max.append('0'); // 0을 추가
                        }
                    }else{ // K
                        max.append('5');
                    }
    • 1. 최댓값을 위해 현재까지의 cntM이 1 이상인 경우:
      • '5'를 추가하고 cntM 개수만큼 '0'을 추가합니다.                                                                                                     (50 이 MK 이고 500이 MMK이므로 K가 있을 때 M의 개수와 0의 개수는 동일)
      • max는 "50"이 됩니다.
    • 2. cntM이 0인 경우:
      • K만 있는 경우이므로 단순히 '5'를 추가합니다.
      • (이 예제에서는 해당되지 않음)
        // 2. 최솟값 나오게
                    // 151 최소
                    // => M + K + M
                    if(cntM > 0) { // MK
                        min.append('1'); // M을 1로 변환
                        for(int j = 1; j < cntM; j++) {
                            min.append('0'); // 나머지 M은 0으로
                        }
                        min.append('5'); // 현재 K를 5로 변환
                    }else{
                        min.append('5'); 
                    }
    
                    cntM = 0;

     

    • 최솟값을 위해 현재까지의 cntM이 1 이상인 경우:
      • cntM이 1이므로 첫 번째 'M'을 '1'로 변환하고, 나머지 'M'은 없으므로 '0'을 추가하지 않고 '5'를 추가합니다.
      • min은 "15"가 됩니다.
    • cntM이 0인 경우:
      • 단순히 '5'를 추가합니다.
      • (이 예제에서는 해당되지 않음)
    • cntM을 0으로 초기화합니다. ( 'K'를 만났을 때까지의 'M' 개수를 다 처리하고 나면 다시 새로운 연속된 'M'의 개수를 세기 위해 초기화하는 것)

     

     

    4. 남은 'M' 처리

    // 남은 M 처리
            if(cntM > 0) {
                // 최대값
                for(int j = 0; j < cntM; j++) {
                    max.append('1');  // 남은 M 모두 1로 변환
                }
                // 최솟값
                min.append('1');
                for(int j = 1; j < cntM; j++) {
                    min.append('0'); 
                }
            }
    • 문자열을 모두 순회한 후 남은 'M'이 있는지 확인합니다.
    • 최댓값을 위해 남은 cntM만큼 '1'을 추가합니다.
      • cntM이 1이므로 '1'을 추가합니다.
      • 최종적으로 max는 "501"이 됩니다.
    • 최솟값을 위해 첫 번째 'M'을 '1'로 변환하고, 나머지 'M'은 없으므로 '0'을 추가하지 않습니다.
      • cntM이 1이므로 '1'을 추가합니다.
      • 최종적으로 min는 "151"이 됩니다.

     


    요약

    • 최댓값:
      • 'M'을 '1'로 변환하고, 'K'를 '5'로 변환하여 '0'을 추가합니다.
      • MKM -> '5' (현재까지의 M 개수: 1) + '0' + '1' -> 501

     

    • 최솟값:
      • 첫 번째 'M'을 '1'로 변환하고 나머지 'M'은 '0'으로 변환한 뒤 'K'를 '5'로 변환합니다.
      • MKM -> '1' + '5' + '1' -> 151

     

Designed by Tistory.