컴굥일지
[BOJ/백준 20301][C++] 반전 요세푸스 본문
반응형
문제
https://www.acmicpc.net/problem/20301
문제 내용
1~N번까지의 사람이 원을 이루며 앉아있고, 계속해서 K번째 사람을 지워나가면 된다.
이때, M명의 사람이 제거될 때마다 방향을 바꿔나가면 된다.
문제에서는 사람을 지워나가는 순서를 출력하기를 바란다.
아래 링크는 백준 1158 요세푸스 문제이다.
이 문제에서 'M명의 사람이 제거될 때마다 방향을 바꾼다'라는 조건을 추가하면 지금 풀고자 하는 문제가 된다.
문제 풀이
백준 1158 요세푸스 문제는 queue로 풀면 됐었다.
하지만 이 문제는 deque를 이용해야 한다.
deque는 queue와 stack의 장점을 모두 가지고 있다는 특징이 있다.
deque는 양 끝에서 push, pop이 모두 가능하다.
이 문제에서는 방향을 바꿔가며 사람을 삭제해야 하기 때문에 deque를 사용해야 한다.
먼저, 1~n을 담은 deque를 만든다.
이후, 순방향일 때는 앞에서 k-1명을 pop 하고 뒤에 push 하면 된다.
그럼 deque의 front에는 우리가 제거해야 할 k번째 사람이 남는다.
이를 출력해주면 된다.
역방향일 때는, 뒤에서부터 k-1명을 pop 하고 앞에 push 해주면 된다.
deque의 back에는 우리가 제거하고자 하는 k번째 사람이 남는다.
이를 출력해주면 된다.
사람 한 명을 제거할 때마다, count변수의 값을 늘려준다.
count의 값이 m과 동일해지면, 방향을 바꾸면 된다.
코드
#include <iostream>
#include <deque>
using namespace std;
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
//입력
int n, k, m;
cin >> n >> k>> m;
deque<int>dq;
for (int i = 1; i <= n; i++) dq.push_back(i);
//문제 해결
int count = 0;
bool check = true;
while (!dq.empty()) {
if (check) { //앞을 빼서 뒤에 넣는다.
for (int i = 0; i < k - 1; i++) {
dq.push_back(dq.front());
dq.pop_front();
}
cout << dq.front() << '\n';
dq.pop_front();
}else{ //뒤를 빼서 앞에 넣는다.
for (int i = 0; i < k - 1; i++) {
dq.push_front(dq.back());
dq.pop_back();
}
cout << dq.back() << '\n';
dq.pop_back();
}
count++;
if (count == m) {
check = !check;
count = 0;
}
}
}
반응형
'알고리즘 > 코테 문제' 카테고리의 다른 글
[BOJ/백준 9657][C++] 돌 게임 3 (0) | 2022.03.18 |
---|---|
[BOJ/백준 9655][C++] 돌 게임 (0) | 2022.03.17 |
[BOJ/백준 18115][C++] 카드 놓기 (0) | 2022.03.15 |
[BOJ/백준 14713][C++] 앵무새 (0) | 2022.03.14 |
[BOJ/백준 19941][C++] 햄버거 분배 (0) | 2022.03.11 |
Comments