강의로 돌아가기
전현서

간단한 해설

이 문제는 팩토리얼과 매우 깊은관계가 있는 문제입니다.
팩토리얼을 모르시면 한 번 알아보시는 것도 좋습니다.

[1, 2, 3, 4] 라는 배열이 존재합니다.
해당 배열에서 나올 수 있는 순열은 4! = 24입니다.
여기서 좀만 더 생각해보면, 앞자리가 각각 1, 2, 3, 4가 시작되는 부분은 언제인지 추측이 가능합니다.
24를 4로 나누어주면 됩니다. 그럼 6이죠? 그럼 6번째 마다 앞자리가 바뀌는 것이 됩니다.
사실 6은 3!입니다. 즉 현재의 배열의 길이보다 하나 작은 팩토리얼만큼 나누어 떨어지는 겁니다.
그럼 n자리부터 1자리까지 그 행동을 반복한다면, 여러분은 답에 쉽게 구할 수 있을겁니다.
그럼 가장 우선적으로 해야할 일은 무엇일까요?

바로, 팩토리얼을 구하는겁니다.
계산할때마다, 팩토리얼을 구하는 행위는 매우 비효율적인 연산에 가깝습니다.
그래서 dp를 사용하여, bottom-up이나 top-down방식 중에 하나 골라 팩토리얼값을 미리 구해 저장해둡니다.
0! = 1! = 1임을 명심해둡시다.

[1, 2, 3, 4]에서 k=6인 경우를 한 번 구해봅시다.
k / factorial(n - 1) 의 연산을 수행하게 됩니다. 현재 배열의 길이 n은 4를 가지므로
factorial(n - 1) = factorial(3) = 6이 됩니다. k는 6인데... 이거 나누어지면, 곤란합니다.
잘 생각해보면, 위의 배열에서 6번째에 와야 할 값은 2가 아니라 1이 와야합니다.

[1, 2, 3, 4] > [1, 2, 4, 3] > [1, 3, 2, 4] > [1, 3, 4, 2] > [1, 4, 2, 3] > [1, 4, 3, 2] 와 같은 순으로
6번째 위치의 앞자리는 2가 아니라 1입니다. 처음에 [1, 2, 3, 4]라는 경우가 포함 되었기 때문에,
우리는 항상 인덱스를 계산할 때, k 대신 (k - 1)으로 계산해야합니다.
이렇게 되면 계산 결과는 5 / 6이 되어 몫이 0이 되어 1을 인덱스로 가져올 수 있게됩니다.

그리고 남은 값이 존재하겠죠?
%연산을 이용해 k % factorial(n-1) 을 남은 값으로 k에 지정합니다.
남은 값을 계산할 때는, (k-1)을 대입하지 않습니다. 위에서 한 연산은 단지, 나누어 떨어지지 않기 위한
일시적인 대책이지만, 실제로 남은 값은 원래 기존 k값에 (n-1)!을 나눈 나머지 값이 맞습니다.
여기서도 (k-1)을 사용하여 나머지 연산을 하게 되면, 아마, k가 음수가 되는 것은 물론이와, 제대로 된 값을
도출하기는 힘들것입니다.

그리고 정답에 배열의 값을 인덱스로 참조하여 답을 하나씩 추가 해줍니다.
n값이 0이 될때 까지만 반복합니다. 또한 배열에서 정답을 추가하면 기존 배열에는 추가된 답을 지워줍니다.

간단하게 나마 도움이 되었으면 합니다.
나누기와 나머지 연산을 활용해 푸는 문제는 숫자하나차이로 많이 헷갈리는 문제입니다.

  • 유재희

    Nice 해설 b

    유재희―2022.11.26 18:13
  • 서지희

    감사합니다!

    서지희―2023.01.12 15:24
  • jmk4560@gmail.com

    감사합니다! 덕분에 해결하였습니다.

    jmk4560@gmail.com―2023.09.14 20:39
  • NileTheKing

    NileTheKing―2026.04.05 12:07
0 개의 답변
답변 쓰기
이 입력폼은 마크다운 문법을 지원합니다.