250x250
250x250
JinSeopKim
Hello World!
JinSeopKim
전체 방문자
오늘
어제
  • 분류 전체보기 (168)
    • Artificial intelligence (14)
      • DeepDiveToAI (3)
      • Pytorch (3)
      • Etc (8)
    • Back-end (19)
      • Spring (10)
      • JPA (9)
    • Language (24)
      • Python (3)
      • Java (11)
      • Swift (10)
    • Math (4)
      • Linear Algebra (4)
    • CodingTest (79)
      • Algolithm (12)
      • Backjoon (25)
      • Programmers (42)
    • Etc (27)
      • Book Review (3)
      • Adsp (6)
      • Life (2)
      • Docker (1)
      • odds and ends (15)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • GitHub

인기 글

태그

  • 구현
  • 코딩테스트
  • 파이썬
  • BOJ
  • JAVA8
  • 선형대수
  • AI
  • ios
  • 개발자
  • 알고리즘
  • 프로그래머스
  • Front-end
  • 백준
  • ADsP
  • java
  • 머신러닝
  • Python
  • 개발
  • BFS
  • 카카오
  • 자바
  • uArm
  • SpringMVC
  • swift
  • certificate
  • 문제풀이
  • 브루트포스
  • data
  • DP
  • JPA

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
JinSeopKim

Hello World!

[PGM_87946] 피로도 (java)
CodingTest/Programmers

[PGM_87946] 피로도 (java)

2022. 2. 26. 11:40
728x90
728x90

문제링크

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

 

코딩테스트 연습 - 피로도

XX게임에는 피로도 시스템(0 이상의 정수로 표현합니다)이 있으며, 일정 피로도를 사용해서 던전을 탐험할 수 있습니다. 이때, 각 던전마다 탐험을 시작하기 위해 필요한 "최소 필요 피로도"와 던

programmers.co.kr

문제풀이

👨🏻‍💻 핵심 스킬 👨🏻‍💻
 완전탐색(순열)

1. 문제 이해

- 던전을 도는 xx게임은 피로도를 소모하게된다. 던전에 대한 피로도는 최소피로도와 소모피로도가 있다. 최소 피로도는 던전을 돌기위한 최소의 피로도이며 소모피로도는 던전을 돌았을 때 소모되는 피로도이다.

 

던전들의 최소피로도 그리고 소모피로도에 대한 값의 정보와 피로도가 주어졌을 때 유저가 최대 몇개의 던전을 돌 수 있는지 알아보자.  던전은 한번씩만 돌 수있다.

 

2. 접근방법

- 순열로 던전을 도는 순서를 모두 탐색하는 방법으로 접근하였다. 던전을 도는 순서에 대한 모든 순열을 구하여 던전을 직접 돌고, 가장 많이 던전을 도는 방법을 알아보았다.

 

3. 세부 해결방안

//순열의 다음 위치를 찾아주기
private boolean nextPermutation(int[] numbers){
    int prevIndex;
    int n = numbers.length;
    int nextIndex = n-1;
    int changeIndex = -1;

    for(int i = n-2; i >= 0; i--){
        prevIndex = nextIndex;
        nextIndex = i;

        if(numbers[nextIndex] < numbers[prevIndex]){
            changeIndex = nextIndex;
            break;
        }
    }

    if(changeIndex == -1)
        return false;

    for(int i = n-1; i > changeIndex; i--){
        if(numbers[i] > numbers[changeIndex]){
            swap(numbers, i, changeIndex);
            break;
        }
    }
    while(++changeIndex < --n){
        swap(numbers,changeIndex,n);
    }
    return true;
}

//배열의 순서변경
private void swap(int[] numbers, int a, int b){
    int temp = numbers[a];
    numbers[a] = numbers[b];
    numbers[b] = temp;
}

Permutation은 오름차순 -> 내림차순으로 이동하면서 찾을 수 있도록 해주었다. 만약 모든 수가 내림차순이라면 더이상 변경할 값이 없기 때문에 순열을 모두 탐색했다고 할 수 있다.

 

//정해진 순서로 던전을 입장했을 때 입장한 던전의 수
public int doDungeons(int[] permutation, int[][] dungeons, int p){
    int count = 0;
    for(int i = 0; i < permutation.length; i++){
        //피로도가 던전입장을 위한 최소 피로도보다 작은경우
        if(dungeons[permutation[i]][0] <= p){
            p -= dungeons[permutation[i]][1];
            count++;
        }
    }
    return count;
}

정해진 순서로 던전에 대한 피로도와 비교해 실제로 입장할 수 있는 던전의 수를 리턴받게 하였다.

 

구현코드

package pgm_87946;

public class Solution {
    public int solution(int k, int[][] dungeons) {
        int[] permutation = new int[dungeons.length];
        for(int i = 0; i < permutation.length; i++){
            permutation[i] = i;
        }
        int max = 0;
        do{
            //모든 경우에 대해 던전을 돌고 최대값을 찾아준다.
            int count = doDungeons(permutation, dungeons, k);
            max = max > count ? max : count;
        }while (nextPermutation(permutation));
        return max;
    }

        //정해진 순서로 던전을 입장했을 때 입장한 던전의 수
        public int doDungeons(int[] permutation, int[][] dungeons, int p){
            int count = 0;
            for(int i = 0; i < permutation.length; i++){
                //피로도가 던전입장을 위한 최소 피로도보다 작은경우
                if(dungeons[permutation[i]][0] <= p){
                    p -= dungeons[permutation[i]][1];
                    count++;
                }
            }
            return count;
        }

    //순열의 다음 위치를 찾아주기
    private boolean nextPermutation(int[] numbers){
        int prevIndex;
        int n = numbers.length;
        int nextIndex = n-1;
        int changeIndex = -1;

        for(int i = n-2; i >= 0; i--){
            prevIndex = nextIndex;
            nextIndex = i;

            if(numbers[nextIndex] < numbers[prevIndex]){
                changeIndex = nextIndex;
                break;
            }
        }

        if(changeIndex == -1)
            return false;

        for(int i = n-1; i > changeIndex; i--){
            if(numbers[i] > numbers[changeIndex]){
                swap(numbers, i, changeIndex);
                break;
            }
        }
        while(++changeIndex < --n){
            swap(numbers,changeIndex,n);
        }
        return true;
    }

    //배열의 순서변경
    private void swap(int[] numbers, int a, int b){
        int temp = numbers[a];
        numbers[a] = numbers[b];
        numbers[b] = temp;
    }
}
잘못된 지식이나 궁금한 내용이 있을 경우 편하게 댓글 남겨주시면 감사하겠습니다 :)

 

728x90
728x90
저작자표시 비영리 (새창열림)

'CodingTest > Programmers' 카테고리의 다른 글

[PGM_12985] 예상 대진표 (java)  (0) 2022.02.28
[PGM_42577] 전화번호 목록 (java)  (0) 2022.02.27
[PGM_1844] 게임 맵 최단거리 (java)  (0) 2022.02.23
[PGM_42860] 조이스틱 (java)  (0) 2022.02.22
[PGM_42839] 소수 찾기  (0) 2022.02.22
    'CodingTest/Programmers' 카테고리의 다른 글
    • [PGM_12985] 예상 대진표 (java)
    • [PGM_42577] 전화번호 목록 (java)
    • [PGM_1844] 게임 맵 최단거리 (java)
    • [PGM_42860] 조이스틱 (java)
    JinSeopKim
    JinSeopKim
    기록📚

    티스토리툴바