1. 程式人生 > >poj3517約瑟夫問題

poj3517約瑟夫問題

n) ace return color tor name syn names 不同的

直接套公式+

假設除去第k個人。

0, 1, 2, 3, ..., k-2, k-1, k, ..., n-1  //original sequence (1)

0, 1, 2, 3, ..., k-2, , k, ..., n-1  //get rid of kth person (2)

k, k+1, ..., n-1, 0, 1, ..., k-2  //rearrange the sequence (3)

0, 1, ..., n-k-1, n-k, n-k+1, ..., n-2  //the n-1 person (4)

我們假設f(n)的值為n個人中最後存活的人的序號,則

註意到(2)式(3)式(4)式其實是同一個序列。

註意(1)式和(4)式,是同一個問題,不同的僅僅是人數。

假設我們已知f(n-1),即(4)式中最後剩下的人的序號,則(3)式所對應的序號,就是f(n),即(1)式n個人中最後存活的序號。

而從(3)(4)式中我們不難發現有這樣一個遞推式:

f(n) = (f(n-1) + k) % n

顯然,f(1) = 0。

於是遞推得f(n)

因為是從m開始,所以遞推的最後要單獨列出來

普通的約瑟夫是從0開始

技術分享
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include
<stack> #include<vector> #include<cstdio> #include<cassert> #include<iomanip> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define
rs m+1,r,rt<<1|1 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const double g=10.0,eps=1e-7; const int N=35000+10,maxn=500+100,inf=0x3f3f3f; int main() { ios::sync_with_stdio(false); cin.tie(0); int n,m,k; while(cin>>n>>k>>m){ if(!n&&!k&&!m)break; int ans=0; for(int i=2;i<n;i++) ans=(ans+k)%i; cout<<(ans+m)%n+1<<endl; } return 0; } /******************** ********************/
View Code

poj3517約瑟夫問題