출처: https://snupi.tistory.com/31 [SNUPI]

문제 설명

어떤 숫자에서 k개의 수를 제거했을 때 얻을 수 있는 가장 큰 숫자를 구하려 합니다.

예를 들어, 숫자 1924에서 수 두 개를 제거하면 [19, 12, 14, 92, 94, 24] 를 만들 수 있습니다. 이 중 가장 큰 숫자는 94 입니다.

문자열 형식으로 숫자 number와 제거할 수의 개수 k가 solution 함수의 매개변수로 주어집니다. number에서 k 개의 수를 제거했을 때 만들 수 있는 수 중 가장 큰 숫자를 문자열 형태로 return 하도록 solution 함수를 완성하세요.

 

제한 조건

  • number는 1자리 이상, 1,000,000자리 이하인 숫자입니다.
  • k는 1 이상 number의 자릿수 미만인 자연수입니다.

입출력 예

number k return
"1924" 2 "94"
"1231234" 3 "3234"
"4177252841" 4 "775841"

 

Greedy02.java

// https://programmers.co.kr/learn/courses/30/lessons/42883
// 20.8.7. ventania1680
package Programmers;

import java.util.Stack;

public class Greedy02 {
    public static String solution(String number, int k) {
        char[] answer = new char[number.length() - k];
        Stack<Character> s = new Stack<>();

        for (int i = 0; i < number.length(); i++) {
            char c = number.charAt(i);
            while(!s.isEmpty() && s.peek() < c && k-- > 0)
                s.pop();
            s.push(c);
        }

        for (int i = 0; i < answer.length; i++)
            answer[i] = s.get(i);

        return new String(answer);
    }
}

 

스택 클래스 사용과 그리디 알고리즘으로 간단하게 풀 수 있는 문제.

 

스택 최상단에 있는 수가 현재 위치의 수보다 작은 경우에 팝(POP)한다.

 

https://programmers.co.kr/learn/courses/30/lessons/42883

 

코딩테스트 연습 - 큰 수 만들기

 

programmers.co.kr

https://github.com/ventania1680/algorithm/blob/master/Algorithm/src/Programmers/Greedy02.java

 

ventania1680/algorithm

Contribute to ventania1680/algorithm development by creating an account on GitHub.

github.com

 

문제 설명

 

점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.

전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.

 

제한사항

  • 전체 학생의 수는 2명 이상 30명 이하입니다.
  • 체육복을 도난당한 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
  • 여벌의 체육복을 가져온 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
  • 여벌 체육복이 있는 학생만 다른 학생에게 체육복을 빌려줄 수 있습니다.
  • 여벌 체육복을 가져온 학생이 체육복을 도난당했을 수 있습니다. 이때 이 학생은 체육복을 하나만 도난당했다고 가정하며, 남은 체육복이 하나이기에 다른 학생에게는 체육복을 빌려줄 수 없습니다.

입출력 예

n lost reserve return
5 [2, 4] [1, 3, 5] 5
5 [2, 4] [3] 4
3 [3] [1] 2

입출력 예 설명

예제 #1
1번 학생이 2번 학생에게 체육복을 빌려주고, 3번 학생이나 5번 학생이 4번 학생에게 체육복을 빌려주면 학생 5명이 체육수업을 들을 수 있습니다.

예제 #2
3번 학생이 2번 학생이나 4번 학생에게 체육복을 빌려주면 학생 4명이 체육수업을 들을 수 있습니다.

 

Greedy01.java

// https://programmers.co.kr/learn/courses/30/lessons/42862
// 20.8.7. ventania1680
package Programmers;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Greedy01 {
    public static int solution(int n, int[] lost, int[] reserve) {
        int answer = n - lost.length;
        boolean[] res = new boolean[31];
        Arrays.fill(res, false);
        Arrays.sort(lost);
        for (int i = 0; i < reserve.length; i++) {
            res[reserve[i]] = true;
        }
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < lost.length; i++)
            list.add(lost[i]);

        for (int i = 0; i < list.size(); i++) {
            int tmp = list.get(i);
            if (res[tmp]) {
                list.remove(i--);
                res[tmp] = false;
                answer++;
            }
        }
        for (int i = 0; i < list.size(); i++) {
            int tmp = list.get(i);
            if (res[tmp - 1]) {
                res[tmp - 1] = false;
                answer++;
            }
            else if (res[tmp + 1]) {
                res[tmp + 1] = false;
                answer++;
            }
        }
        return answer;
    }
}

 

문제 조건에 따라 학생의 수는 최대 30명, 즉 1번부터 30번 학생까지 있다.

 

여벌의 체육복을 가져온 학생을 boolean 배열로 표현했다.

 

여벌 체육복을 가져온 학생이 체육복을 도난당한 경우에는 다른 학생에게 빌려줄 수 없으므로, 해당 경우를 먼저 제외한다.

 

처음에는 lost 배열을 그대로 사용하여 답을 구했더니 여벌 체육복을 가져오고 체육복을 도난당한 학생을 두 번 카운트하게 되어 이를 ArrayList를 사용해서 리스트에서 제거하는 방식으로 중복을 방지했다.

 

https://programmers.co.kr/learn/courses/30/lessons/42862

 

코딩테스트 연습 - 체육복

점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번�

programmers.co.kr

https://github.com/ventania1680/algorithm/blob/master/Algorithm/src/Programmers/Greedy01.java

 

ventania1680/algorithm

Contribute to ventania1680/algorithm development by creating an account on GitHub.

github.com

 

문제 설명

 

Leo는 카펫을 사러 갔다가 아래 그림과 같이 중앙에는 노란색으로 칠해져 있고 테두리 1줄은 갈색으로 칠해져 있는 격자 모양 카펫을 봤습니다.

Leo는 집으로 돌아와서 아까 본 카펫의 노란색과 갈색으로 색칠된 격자의 개수는 기억했지만, 전체 카펫의 크기는 기억하지 못했습니다.

Leo가 본 카펫에서 갈색 격자의 수 brown, 노란색 격자의 수 yellow가 매개변수로 주어질 때 카펫의 가로, 세로 크기를 순서대로 배열에 담아 return 하도록 solution 함수를 작성해주세요.

 

제한사항

  • 갈색 격자의 수 brown은 8 이상 5,000 이하인 자연수입니다.
  • 노란색 격자의 수 yellow는 1 이상 2,000,000 이하인 자연수입니다.
  • 카펫의 가로 길이는 세로 길이와 같거나, 세로 길이보다 깁니다.

입출력 예

brown yellow return
10 2 [4, 3]
8 1 [3, 3]
24 24 [8, 6]

 

BF03.java

// https://programmers.co.kr/learn/courses/30/lessons/42842
// 20.8.6. ventania1680
package Programmers;

public class BF03 {
    public static int[] solution(int brown, int yellow) {
        int sum = brown + yellow;
        for (int row = 3; row < sum; row++) {
            if (sum % row == 0) {
                int col = sum / row;
                if (row * 2 + col * 2 - 4 == brown) {
                    return new int[] {col, row};
                }
            }
        }
        return null;
    }
}

 

완전탐색으로 간단하게 해결할 수 있는 문제.

 

모든 격자의 개수를 나눌 수 있는 수가 곧 가능한 가로, 세로의 크기가 된다.

 

테두리가 곧 갈색 격자의 개수이므로 (가로 * 2 + 세로 * 2 - 4 = 갈색 격자 개수)라는 식이 성립한다.

 

가능한 모든 가로, 세로 크기에 대해서 위 식을 만족하는지 검사하여 문제의 답을 구할 수 있다.

 

https://programmers.co.kr/learn/courses/30/lessons/42842

 

코딩테스트 연습 - 카펫

Leo는 카펫을 사러 갔다가 아래 그림과 같이 중앙에는 노란색으로 칠해져 있고 테두리 1줄은 갈색으로 칠해져 있는 격자 모양 카펫을 봤습니다. Leo는 집으로 돌아와서 아까 본 카펫의 노란색과 ��

programmers.co.kr

 

https://github.com/ventania1680/algorithm/blob/master/Algorithm/src/Programmers/BF03.java

 

ventania1680/algorithm

Contribute to ventania1680/algorithm development by creating an account on GitHub.

github.com

 

+ Recent posts