Algorithm/Java

[백준/JAVA] 21314번: 민겸 수

dbfl9911 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

 

반응형