[ 문제 ] : https://www.acmicpc.net/problem/1158
1158번: 요세푸스 문제
첫째 줄에 N과 K가 빈 칸을 사이에 두고 순서대로 주어진다. (1 ≤ K ≤ N ≤ 5,000)
www.acmicpc.net
[ 문제 접근 ]
- 요세푸스 문제라는 유명한 문제인데, 처음 보고는 어떻게 풀어야할지 감이 안잡혔다.
컨셉만 알면 구현은 쉬운데 컨셉을 생각하기까지 버벅거렸다.
1.Queue 를 이용하거나 2.Circular Linked List 를 사용하거나 3.Recursion 으로 풀 수 있다.
[ 최종 코드 ]
#include<iostream>
#include<queue>
using std::cout; using std::cin;
int n, k;
int main() {
std::ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> n >> k;
std::queue<int> que;
for (int i = 1; i <= n; i++) {
que.push(i);
}
cout << "<";
while (!que.empty()) {
for (int i = 0; i < k-1; i++) {
int cur = que.front();
que.pop();
que.push(cur);
}
if (que.size() == 1) cout << que.front();
else { cout << que.front() << ", " ; }
que.pop();
}
cout << ">";
return 0;
}
[ Queue 를 이용한 비슷한 코드 ]
#include<iostream>
#include<queue>
using namespace std;
void josephus(int n, int k) {
queue<int> survivors;
int* arr = new int[n];
for (int i = 1; i <= n; ++i) survivors.push(i);
int cnt = 1; // 사람 카운트
int i = 0; // 배열 idx
while (!survivors.empty()) {
if (cnt == k) {
arr[i++] = survivors.front(); // arr 배열에 저장.
survivors.pop();
cnt = 1;
}
else {
survivors.push(survivors.front());
survivors.pop();
cnt++;
}
}
// arr를 이용해서 range based for문 사용하려고 했는데
// 동적할당한 arr는 range based for loop을 사용할수 없다. ===> vector를 애용하자!!
cout << "<";
for (int i = 0; i < n-1; i++) {
cout << arr[i] << ", ";
}
cout << arr[n - 1] << ">";
}
int main() {
int k, n;
cin >> n >> k;
josephus(n, k);
return 0;
}
[ 원형 리스트를 컨셉을 이용한 방법 ]
#include<iostream>
#include<algorithm>
#include<vector>
using std::cout; using std::cin;
using std::vector;
int n, k;
int pre[5001];
int next[5001];
int main() {
std::ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
vector<int> vec; // 요세푸스 순열 저장할 변수.
cin >> n >> k;
// 원형 연결 리스트 생성
// 맨 처음 노드와 마지막 노드가 서로를 가리키도록.
for (int i = 1; i <= n; i++) {
pre[i] = (i == 1) ? n : i - 1;
next[i] = (i == n) ? 1 : i + 1;
}
int size = n;
int cnt = 1;
for (int cur = 1; size != 0; cur = next[cur]) {
if (cnt == k) {
// 제거 ( 실제 제거는 안하지만 값 인덱싱 못하게 끔 )
pre[next[cur]] = pre[cur];
next[pre[cur]] = next[cur];
vec.push_back(cur);
cnt = 1;
--size;
}
else {
cnt++;
}
}
cout << "<";
for (size_t i = 0; i < vec.size(); ++i) {
cout << vec[i];
if (i != vec.size() - 1) cout << ", ";
}
cout << ">";
return 0;
}
[ Key Point ]
[ 다른 사람 풀이 ]
'PS > BaekJoon' 카테고리의 다른 글
[6198] 옥상 정원 꾸미기 - 스택/Monotone Stack ★★★☆ / 복습 ○ (0) | 2021.11.24 |
---|---|
[1874] 스택 수열 - 스택 ★★☆☆ / 복습 ○ (0) | 2021.11.24 |
[5397] 키로거 - 연결 리스트 ★☆☆☆ / 복습 ○ (0) | 2021.11.23 |
[1406] 에디터 - 연결 리스트 ★☆☆☆ / 복습 ● (0) | 2021.11.23 |
[3273] 두 수의 합 - 배열/투 포인터 ★☆☆☆ / 복습 ○ (0) | 2021.11.23 |