-
Notifications
You must be signed in to change notification settings - Fork 0
2023.11.16 ‐ 2023.11.22
yumyeonghan edited this page Dec 29, 2023
·
6 revisions
- 그리디 문제
- 반복문을 통해 1 부터 순차적으로 더해가면서, 만약 주어진 S(자연수의 합)을 넘을 경우
break
- 이때 더해진 숫자가 몇개인지 카운트(n++)
- 위의 조건일 때
break
하는 이유- 1부터 순차적으로 더해나갔기 때문에 합이 S를 넘어가면 언제든지 n개의 숫자로 S를 만들 수 있음
// 2번 과정
while (true) {
index++;
sum += index;
// 순차적으로 더해나갔는데 만약 S를 넘어가면 해당 n 반환 => 언제든지 n개의 숫자로 원하는 숫자를 만들 수 있으므로
if (sum > S) {
break;
}
n++;
}
- 정렬과 그리디 문제
- 인덱스를 서류 순위, 값을 면접 순위로 배열 초기화 (정렬)
- 서류 1등 지원자를 처음 기준으로 두고, 다른 지원자들과 면접 순위를 비교해 가며 순회
- 면접 순위가 더 높은 사람이 있으면 카운팅 + 1
- 이때 해당 사람의 면접 순위를 기준으로 둠
// 3번 과정
/**
* 2번째 예시
* 1, 4 선발
* 2, 5
* 3, 6
* 4, 2 선발
* 5, 7
* 6, 1 선발
* 7, 3
*/
int base = tmp[1]; // 2번 과정의 배열
for (int j = 2; j <= m; j++) {
if (tmp[j] < base) {
base = tmp[j];
count++;
}
}
- 현재 위치보다 앞을 순회
- 가장 처음 같은 글자를 찾은것이 가장 가까운 수이기 때문에 해당 값을 정답처리
// 1-2번 과정
for (int i = 0; i < answer.length; i++) {
// 현재 위치보다 앞을 순회하며,
for (int j = i; j >= 0; j--) {
// 가장 처음 같은 글자를 찾으면 그것이 가장 가까운 수이기 때문에
// answer[i] == 0 조건 추가
if (s.charAt(i) == s.charAt(j) && answer[i] == 0) {
answer[i] = i - j;
}
}
if (answer[i] == 0) {
answer[i] = -1;
}
}
- 주어진 로프의 개수에 의한 로프를 담을 배열을 생성
- 배열 입력 받음
- 최대 중량을 구하기 위해 배열 정렬
- 최소 중량 로프부터 w/k 값을 계산 하여 반복문을 통해 최대 증량을 구함
- 코드 단락, 이유 1
// 1~2번 해결 과정
int N = sc.nextInt(); //주어진 로프의 개수
int[] arr = new int[N]; //로프를 담을 배열
for (int i = 0; i < N; i++) {
arr[i] = sc.nextInt();
}
- 코드 단락, 이유 2
// 3~4번 해결 과정
//"각" 로프가 버틸 수 있는 최대 중량을 구하기 위해 배열 정렬
Arrays.sort(arr);
//최소 중량 로프부터 (w/k)를 계산
int maximum = 0;
for (int i = 0; i < arr.length; i++) {
maximum = Math.max(maximum, arr[i] * (N - i));
}
- 수의 범위가 Long 범위도 넘어가므로 String 형태로 수를 입력 받음
- 30의 배수가 되려면 10의 배수도 되야 하므로 입력 받은 수에
- 0이 포함 된다면 숫자를 섞는 과정을 진행
- 0이 없다면 숫자를 섞어도 30의 배수를 만들 수 없으므로 “-1” 출력
- 출력할 배열의 크기를 주어진 수의 자릿수만큼 초기화
- 각 자릿수의 합을 sum 변수에 더해나감
- 가장 큰 수를 만들기 위해 배열 정렬 → 역순 출
- 각 자릿수의 합을 더한 sum 변수가
- 3으로 나누어 떨어지면 30의 배수가 되는 가장 큰 수를 출력
- 아니라면 만들 수 있는 30의 배수가 존재하지 않으므로 -1을 출력
String s = sc.next(); //미르코가 본 양수 (최대 10만개의 숫자로 구성)
//30의 배수 = 10의 배수 -> 10의 배수이면? "0"을 포함
if (s.contains("0")) {
//만들고 싶어하는 수를 출력할 배열
int[] num = new int[s.length()];
int sum = 0;
for (int i = 0; i < num.length; i++) {
num[i] = Integer.parseInt(String.valueOf(s.charAt(i)));
sum += num[i];
}
Arrays.sort(num);//가장 큰 수를 만들어야 하므로 배열을 정렬
//30의 배수: 각 자릿수의 합이 3의 배수
if (sum % 3 == 0) {
for (int i = num.length - 1; i >= 0; i--) {
System.out.print(num[i]);
}
}
//아닐 시 만들 수 있는 30의 배수가 존재하지 않음
else{
System.out.println(-1);
}
}
//"0"이 없으면 30의 배수를 만들 수 없음
else{
System.out.println(-1);
}
- 나눈 문자열을 담을 리스트를 초기화
- 첫 글자 나온 횟수와 다른 글자 나온 횟수 변수 선언
- 나눌 문자를 담을 문자열 변수 선언 및 첫 글자로 초기화
- 반복문 돌면서 첫 글자 나온 횟수와 다른 글자 나온 횟수 비교
- 문자열을 초기화한 상태 → 첫 글자 횟수와 다른 글자 횟수가 같아서 리스트에 누적 문자열을 담은 상태이므로 첫 글자 초기화
- 아니라면 count 변수 더해 나감
처음 글자 횟수와 다른 글자 횟수가 같다면 리스트에 여태까지 누적한 문자열을 더한 후 문자열 초기화 & count 변수 초기화
- 문자열 끝까지 count 과정을 진행했을 때, tmp 변수가 공백, 즉, 문자열 일부가 남아 있다면 리스트에 더함
- 리스트의 사이즈를 출력: 리스트 사이즈의 개수: 분해한 문자열의 개수
//1~3번 풀이 과정
var a = new ArrayList<String>();
int count_first = 1; //첫 글자 나온 횟수
int count_other = 0; //다른 글자 나온 횟수
char first = s.charAt(0); //첫 글자
String tmp = String.valueOf(s.charAt(0)); //나눌 문자
//4~5번 풀이 과정
for (int i = 1; i < s.length(); i++) {
char c = s.charAt(i);
//문자열을 초기화한 상태에서는 첫 글자만 초기화함
if (tmp.equals("")) {
first = c;
}
else {
if (c == first) {
count_first += 1;
}
else{
count_other += 1;
}
}
tmp += c; //문자열 누적
//처음 글자 횟수와 다른 글자 횟수가 같다면
//리스트에 여태까지 누적한 문자열을 더한 후 문자열 초기화 & count 초기화
if (count_first == count_other) {
a.add(tmp);
tmp = "";
count_first = 1;
count_other = 0;
}
}
//문자열 끝까지 진행했을 때 리스트에 들어가지 않은 경우
if (!tmp.equals("")) {
a.add(tmp);
}
return a.size();
- 무적권을 활용하여 최대한 많은 라운드를 진행함 → greedy
- 무적권의 개수와 적의 수를 담은 배열의 크기가 같다면 해당 길이를 리턴
- 무적권 사용 여부를 판단하기 위한 우선순위 큐 선언: 내림차순 정렬
- 적 배열의 길이 만큼 반복문을 진행
- 이때, 적의 수보다 막을 병사가 부족하고 무적권이 없다면 반복문 종료
- 큐에 적의 병사 수를 더해나감
- 현재 적보다 병사수가 부족하다면 최소로 병사 수를 소비한 라운드를 다시 병사 수에 더한 후 현재 라운드는 무적권을 사용함
- 코드 단락, 이유 1
// 1~2번 해결 과정
//모든 라운드를 막을 수 있는 경우(무적권 개수 == 적 배열의 길이)
if (k == enemy.length) {
return enemy.length;
}
//무적권 사용 여부를 판단하기 위함 & 우선순위 큐 오름차순 정렬
PriorityQueue<Integer> queue = new PriorityQueue<>(Collections.reverseOrder());
- 코드 단락, 이유 2
// 3~4번 해결 과정
for (int i = 0; i < enemy.length; i++) {
//병사가 부족하고 무적권이 없다면 공격을 막을 수 없으므로 반복문 종료
if (n < enemy[i] && k == 0) {
break;
}
queue.offer(enemy[i]);
//현재 적보다 병사 수가 부족하면
//최소로 병사 수를 소비한 라운드를 다시 병사 수에 더한 후 무적권 사용
if (!queue.isEmpty() && enemy[i] > n) {
n += queue.poll();
k -= 1;
}
n -= enemy[i];
answer += 1; //막을 수 있는 라운드는 계속 증가
}