And Then There Was One | Aizu Online Judge
ヨセフスの問題とか、ヨセフスの芋とか言われるやつ。
n人いて、m番目の人からはじめてk間隔で処刑していくヨセフスの問題という設定。
シミュレーションだと間に合わないので、「ヨセフスの問題」とかでググると、
f(n,k) = (f(n-1,k) + k) Mod n (ただし、f(1,k) = 0)という漸化式が見つかる。
それをそのまま関数に書き出すと、O(n)で残る人が判定できる。
ただし、この関数は0-indexed(0~n-1番目)の形で返ってくるのと、m人目からはじまるので上手く工夫してやる。
サンプルが合わない人へ: m番目の人はまず初めに処刑されます。(重要)
#include <iostream> #include <cstring> using namespace std; int f(int n,int k){ if(n == 1) return 0; return (f(n-1,k) + k) % n; } int main(){ int n,m,k; while(cin >> n >> k >> m , n){ m = (m-k+1+n)%n; cout << (f(n,k)+m-1+n)%n+1 << endl; } }