---
# System prepended metadata

title: Josephus Problem

---

# Josephus Problem

## 題目
n個人圍成一個環，數k個人後殺掉那個人，剩下的人再圍，直到殺到剩下最後一個，最後存活下來的那個人就贏了。給定n,k，求出最後贏的人。

## 公式解
上一個位置，往後數k格，再mod人數。人數從2迭代到n。
```
//公式: f(n,k)=(f(n-1,k)+k)%n
int josephus(int n, int k) { //非遞回版本
	int s = 0; //只有一個人時，一定剩下他(編號0) f(1,k)=0
	for (int i = 2; i <= n; i++){
        s = (s + k) % i;  //上一個位置，往後數k格，再%人數
	}

	return s;
}
int josephus_recursion(int n, int k) { //遞回版本
	return n > 1 ? (josephus_recursion(n - 1, k) + k) % n : 0;
}
```

## 公式證明

https://www.youtube.com/watch?v=Yeh1_2GyS5s

## Uva 440
先將所有n對所有k的表建出來，再從表裡面找比較快。因為1一定會被刪，所以直接把2(目標)當成0來執行。

```
#include<bits/stdc++.h>

using namespace std;
int survivor[150][600];
void josephus(){
    memset(survivor,0,sizeof(survivor));
    for(int n=2;n<150;++n){
        for(int k=1;k<600;++k){
            survivor[n][k]=(survivor[n-1][k]+k)%n;
        }
    }
}

int main(){
    int n;
    josephus();
    while(cin>>n&&n){
        for(int k=1;k<600;++k){
            if(survivor[n-1][k]==0){
                cout<<k<<endl;
                break;
            }
        }
    }


return 0;
}

```