約瑟夫環問題其實非常簡單,就是一圈人,每次掛掉第k個,下次從他的下一個開始數,再掛掉第k個,直到剩下一個爲止。其中k可以是固定的,也可以是變化的。
約瑟夫問題模擬的複雜度較高,採用遞推是比較合理的方式。
假設有n個人,每次殺死k個。
第一次殺死前編號如下:
0 1 2 … k-1 k k+1 … n-2 n-1 (1)
第一次殺死後編號如下:
0 1 2 … k-2 k k+1 … n-2 n-1 (2)
那麼下一次開始的時候就要這麼看這個編號:
k k+1 k+2 … n-2 n-1 0 1 2 … k-2 (3)
將此編號重新排列:
0 1 2 … n-2-k n-1-k n-k … n-2 (4)
對比(3) (4)可以推導出公式:
x’=(x+k) mod n
其中x’是上一輪的編號,x是後一輪的編號,k爲上一輪殺死的人,n爲上一輪的人數。
例如:http://acm.hdu.edu.cn/showproblem.php?pid=5643在這裏有漢語翻譯http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=677&pid=1004
代碼如下:
/***************************************************************
File Name: 1004.cpp
Author: wxc575843
Mail: [email protected]
Created Time: 六 3/12 21:59:54 2016
**************************************************************/
#include<iostream>
using namespace std;
int dp[5000];
void solve(){
dp[0]=0;
int n;
cin>>n;
for(int i=1;i<n;i++){
dp[i]=(dp[i-1]+n-i)%(i+1);
}
dp[n-1]++;
cout<<dp[n-1]<<endl;
}
int main(){
int n;
cin>>n;
while(n--){
solve();
}
}