반응형
요세푸스 문제
# 문제에 대한 자세한 개요는 검색해보는 것을 추천.
# 대충 요약하면 41명의 사람에 대해서 3명당 한명씩 죽이는 걸 반복했을 때, 마지막 한명이 되어 살아남으려면 몇번째 자리에 있어야 하는가? 라는 문제.
# 점화식을 이용한 수학적 풀이와 이진법을 이용한 풀이도 있지만 이 포스팅에서는 생략했다. 이쪽이 궁금하면 검색해보는 것을 추천.
# 프로그래밍적으로는 원형 리스트를 이용해서 푸는 문제라서 이 시점에서 풀어보았다.
# 구현한 것은 max명의 사람에 대해서 die명당 한명씩 죽일때 live명의 생존자를 보여준다.
# die가 0이면 첫번째 사람부터 차례대로 죽는 경우가 되고, die가 1이면 첫번째 사람 다음 사람부터 차례대로 죽는 경우가 된다.
# 1명이상 건너뛰는 경우는 2이상 입력했을 때이다. die에 max보다 큰 수를 입력해도 잘 작동한다.
solution.h
#pragma once #include <iostream> class CircularList { struct node { int id; bool exist; }; node* capacity; int iIndex; int iSize; int iCount; private: int next(int d); public: void LastN(int live, int die); public: CircularList(int size); virtual ~CircularList(); }; CircularList::CircularList(int size) { capacity = new node[size]; iIndex = 0; iSize = iCount = size; for (int i = 0; i < size; i++) { capacity[i].id = i + 1; capacity[i].exist = true; } } int CircularList::next(int d) { iIndex += d; iIndex %= iSize; while (!capacity[iIndex].exist) { iIndex += 1; if (iIndex == iSize) { iIndex = 0; } } return iIndex; } void CircularList::LastN(int live, int die) { while (iCount != live) { capacity[next(die)].exist = false; iCount--; } printf("생존자 %d명\n", live); for (int i = 0; i < iSize; i++) { if (capacity[i].exist) { printf("%d번 ", capacity[i].id); } } } CircularList::~CircularList() { delete[] capacity; }
problem.cpp
#include "solution.h" int main() { int max = 0; while (true) { std::cout << "총 인원이 몇명인지 입력하세요.\n"; std::cin >> max; if (max <= 0) { getc(stdin); std::cout << "이미 다 죽었습니까?\n"; std::cin >> max; } else { break; } } CircularList solution(max); int live = 0; while (true) { std::cout << "살아남은 인원이 몇명인지 입력하세요.\n"; std::cin >> live; if (live <= 0) { getc(stdin); std::cout << "아무리 그래도 1명이상 살려줍시다. \n"; std::cin >> live; } else if (live > max) { getc(stdin); std::cout << "그만큼의 인원이 없습니다. \n"; std::cin >> live; } else { break; } } int die = 0; std::cout << "몇 명 마다 죽일지 정하세요.\n"; std::cin >> die; solution.LastN(live, die); }
반응형