約瑟夫環問題

約瑟夫環問題其實非常簡單,就是一圈人,每次掛掉第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();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章