Skip to content

Commit

Permalink
[level 2] Title: 줄 서는 방법, Time: 0.01 ms, Memory: 3.82 MB -BaekjoonHub
Browse files Browse the repository at this point in the history
  • Loading branch information
developeSHG committed Nov 16, 2023
1 parent 7bb9d3b commit e02ea03
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 0 deletions.
66 changes: 66 additions & 0 deletions 프로그래머스/2/12936. 줄 서는 방법/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# [level 2] 줄 서는 방법 - 12936

[문제 링크](https://school.programmers.co.kr/learn/courses/30/lessons/12936)

### 성능 요약

메모리: 3.82 MB, 시간: 0.01 ms

### 구분

코딩테스트 연습 > 연습문제

### 채점결과

정확성: 73.7<br/>효율성: 26.3<br/>합계: 100.0 / 100.0

### 제출 일자

2023년 11월 4일 11:53:25

### 문제 설명

<p>n명의 사람이 일렬로 줄을 서고 있습니다. n명의 사람들에게는 각각 1번부터 n번까지 번호가 매겨져 있습니다. n명이 사람을 줄을 서는 방법은 여러가지 방법이 있습니다. 예를 들어서 3명의 사람이 있다면 다음과 같이 6개의 방법이 있습니다.</p>

<ul>
<li>[1, 2, 3]</li>
<li>[1, 3, 2]</li>
<li>[2, 1, 3]</li>
<li>[2, 3, 1]</li>
<li>[3, 1, 2]</li>
<li>[3, 2, 1]</li>
</ul>

<p>사람의 수 n과, 자연수 k가 주어질 때, 사람을 나열 하는 방법을 사전 순으로 나열 했을 때, k번째 방법을 return하는 solution 함수를 완성해주세요.</p>

<h6>제한사항</h6>

<ul>
<li>n은 20이하의 자연수 입니다.</li>
<li>k는 n! 이하의 자연수 입니다.</li>
</ul>

<hr>

<h5>입출력 예</h5>
<table class="table">
<thead><tr>
<th>n</th>
<th>k</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>3</td>
<td>5</td>
<td>[3,1,2]</td>
</tr>
</tbody>
</table>
<h5>입출력 예시 설명</h5>

<p>입출력 예 #1<br>
문제의 예시와 같습니다.</p>


> 출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

//이 문제는 팩토리얼로 전체 경우의 수를 구하고,
//거기서 범위를 연산해서 순서를 구해야 함.
//
//문제의 예시로 설명하면
//n = 3, k = 5일 때,
//전체 경우의 수는 3!= > 6.
//
//이렇게 2마다(전체 경우의 수 / n) 숫자가 바뀜을 알 수 있다.
//2마다 숫자가 바뀌는데, k가 5면 나머지 1, 몫 2가 나온다.

long long Factorial(int n)
{
long long ret = 1;
for (int i = n; i > 1; --i)
ret *= i;
return ret;
}

void Update(int quotient, vector<int>& answer, vector<int>& nums)
{
int temp = nums[quotient];

answer.push_back(temp);
nums.erase(nums.begin() + quotient);
}

vector<int> solution(int n, long long k) {
vector<int> answer, nums;
long long pivot, quotient, remainder;

for (int i = 1; i <= n; ++i) nums.push_back(i);

while (true)
{
pivot = Factorial(n) / n;

remainder = k % pivot;
quotient = k / pivot;

if (remainder == 0)
{
// 나머지가 0이 나온 경우에는 해당 숫자의 마지막 순서.
// 고로 현재 위치의 숫자를 제거하고, 남은 숫자들을 큰 순서대로 나열.
// (1 4 3 2) 6

// 나머지가 0이면 인덱스를 -1
Update(--quotient, answer, nums);

for_each(nums.rbegin(), nums.rend(), [&](const auto& e) {
answer.push_back(e);
});

break;
}
else if (remainder == 1)
{
// 나머지는 1로 몫의 값 순서에서 첫 번째가 된다.
// 남은 숫자들을 작은 순서대로 나열
// (1 2 3 4) 1

Update(quotient, answer, nums);

for_each(nums.begin(), nums.end(), [&](const auto& e) {
answer.push_back(e);
});
break;
}

// 나머지가 0이나 1이 아닌 경우에는 n과k를 갱신하고, 위의 과정을 반복.
// (2 1 4 3) 8

Update(quotient, answer, nums);

--n;
k = remainder;
}

return answer;
}

0 comments on commit e02ea03

Please sign in to comment.