
https://www.acmicpc.net/problem/1158
1158번: 요세푸스 문제
첫째 줄에 N과 K가 빈 칸을 사이에 두고 순서대로 주어진다. (1 ≤ K ≤ N ≤ 5,000)
www.acmicpc.net
요세푸스 순열을 queue를 활용하여 푸는 문제이다.
queue는 선입선출, 처음 넣었던 값이 제일 처음에 나온다는 뜻!
나 혼자 2시간 삽질하다가 다른 사람의 풀이를 참고하여 문제를 풀었다. ㅠㅠ
<처음에 삽질한 과정>
초반에는 queue가 아닌 deque를 사용하여 접근했다.
deque는 중간에서 데이터 삽입, 삭제가 가능했기 때문이다. (그래서 K번째 데이터를 삭제하려고 했음..)

queue에서 index로 데이터 삭제가 가능하다고 생각하고 문제를 풀었다.
그래서
(cur + K - 1 + myqueue.size()) % myqueue.size();
꼴의 규칙을 발견했고, 이를 iterator를 움직이며 deque의 erase 함수를 쓰려고 했다.
하지만!
iterator erase (iterator position);
하지만 deque의 erase함수의 parameter는 자료형이 iterator였고,, iterator에서 % 연산자(나머지 연산자)는 사용할 수 없었다. ㅜㅜ
그래서 배열로 풀어보려 했으나 너무 복잡하여 포기..
<구글링을 통해 풀어낸 과정>
구글링을 통해 다른 멋진 사람들의 코드를 참고하여 문제를 다시 접근해보았다.

queue로 push, pop을 이용하여 원하는 K번째 값을 빼내야 한다.
그러므로 K-1번 push, pop을 반복한다.
queue에서 push는 뒤에서, pop은 앞에서 실행된다. (한방향)
그 다음 front에 있는 값을 출력해주고 pop한다. (이러면 K번째 값이 튀어나와 보이는 것과 마찬가지)
그것을 반복해주면 되는데, 출력 형식에 따라 코드를 조금만 수정하면 된다.
그렇게 완성된 코드이다.
#include <iostream>
#include <queue>
using namespace std;
int N, K;
queue<int> myqueue;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> N >> K;
for (int i = 0; i < N; i++)
{
myqueue.push(i + 1);
}
printf("<");
while (!myqueue.empty()) {
for (int i = 0; i < K - 1; i++) { // 뒤에 push한만큼 앞에서 pop
myqueue.push(myqueue.front());
myqueue.pop();
}
// 위의 for문 과정을 거치고 나면 K번째 수가 나옴
if (myqueue.size() == 1) { // 맨 마지막 과정에선 출력 형식이 살짝 다름
printf("%d>", myqueue.front());
}
else {
printf("%d, ", myqueue.front()); // 출력 후
}
myqueue.pop(); // 없애줌
}
}

자료구조 수강까지 했으면서 이런 거에 헤매는 나,,
공부할 수록 바보가 되어가는 기분이다
'백준' 카테고리의 다른 글
[2630] 색종이 만들기 (0) | 2022.11.08 |
---|---|
[1406] 에디터 (0) | 2022.11.07 |
[10866] 덱 (0) | 2022.11.04 |
[10845] 큐 (0) | 2022.11.03 |
[17413] 단어 뒤집기 2 (0) | 2022.11.02 |
댓글