카테고리 없음

[2주차] 알고리즘 과제

jwk818 2023. 4. 5. 16:04

<백준 1038번>

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

 

1038번: 감소하는 수

음이 아닌 정수 X의 자릿수가 가장 큰 자릿수부터 작은 자릿수까지 감소한다면, 그 수를 감소하는 수라고 한다. 예를 들어, 321과 950은 감소하는 수지만, 322와 958은 아니다. N번째 감소하는 수를

www.acmicpc.net

n번째 감소하는 수를 구하는 문제였다. 모든 숫자를 확인하기에는 시간이 많이 걸릴 것이라고 생각했다. 

0부터 9까지는 [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]로 10부터 99까지는 [10, 20, 21, 30, 31, 32...] 순서로 진행된다.

 

#include <stdio.h>
#include <math.h>

int main(){
    int n;
    scanf("%d", &n);
    
    long long num[10000]; // 감소하는 수를 저장하는 배열
    int first, last; // 한자리 아래의 감소하는 수의 범위를 나타낸다.
    int cur; // 다음 나오는 감소하는 수를 넣을 위치
    
    for(int i = 0; i < 10; i++) // 0~9번째까지는 그대로 0~9를 넣는다.
        num[i] = i;
    
    first = 0; // 한자리 숫자들은 0부터
    last = 9; // 9까지 들어가 있다.
    cur = 10; // 0~9까지 넣었으므로 다음 위치는 10
    
    for(int i = 1; i < 10; i++){ // 10의 몇승인지를 나타낸다. ex) i가 2이면, 10의 2승인 백 대 수들 = 세자리 수들
        for(int j = i; j < 10; j++){ // j는 현재 수의 맨 앞자리 숫자를 의미한다. ex) j가 3이면, 3xx
            for(int k = first; k <= last; k++){ // 한자리 아래의 감소하는 수들을 확인해서 ex) 두자리 수 중 감소하는 수 = 10, 20, 21, 30, 31 등
                if(num[k] / pow(10.0, i-1) < j){ // 해당 수의 맨 앞자리 숫자가 j보다 작다면 ex) 위의 숫자 중 10, 20, 21만 해당한다.
                    num[cur++] = j * pow(10.0, i) + num[k]; // 해당 감소하는 수의 맨 앞에 j를 추가했을 때 감소하는 수가 된다. 그러므로 감소하는 수 배열에 추가 ex) 310, 320, 321 추가
                    if(cur > n){ // n번째 감소하는 수를 찾았다면
                        printf("%lld\n", num[n]); // n번째 감소하는 수 출력
                        return 0;
                    }
                }
            }
        }
        first = last + 1; // 한자리 위의 감소하는 수 중에 첫번째를 가르킴
        last = cur - 1; // 한자리 위의 감소하는 수 중에 마지막을 가르킴
    }
    
    printf("-1\n"); // n번째 감소하는 수가 없으므로 -1 출력
    return 0;
}

0부터 9까지는 이해가 되는데, 두자릿수, 세자리수는 어떻게 해결해야할지 모르겠어 코드를 참고했다. 아직 코드를 직접 짜는 것이 서툴러 시간이 더 필요할 것 같다.

[참고]

https://terry1213.github.io/backjoon/1038/

 

[백준 1038번] 감소하는 수

문제 설명

terry1213.github.io

 

 

<백준 11659번>

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

 

 

 

슬라이딩 윈도우 기법을 사용하여 배열에 누적합을 저장하고, 만약 구간이 2 4 라면 arr[4]-arr[2]를 구해주는 식으로 구간합을 구할 수 있다. 숫자 n과 m을 입력 받고 arr[b] - arr[a-1]을 출력하면 a부터 b까지의 누적합을 구할 수 있다.

[참고]

https://rujang.tistory.com/entry/%EB%B0%B1%EC%A4%80-11659%EB%B2%88-%EA%B5%AC%EA%B0%84-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-4-CC