[Josephus(约瑟夫环)] poj3517poj2244
http://poj.org/problem?id=2244
http://poj.org/problem?id=3517
Josephus环是个基本问题,简单的介绍一下:
J(n)代表n个人站成一个圈(0...n-1(就算你是1-n也没关系,最后可以调整,用0...n-1是为了后面取模运算的方便)),最后活着的人是J(n).
(哦。。如果你不知道约瑟夫环的话,请百度百科)
第一次从0开始查,然后干掉一个(k-1)(从0数到k)所以剩下的元素为0,1,2,...k-2,k,k+1,...n-1.我们对其重新编号
0 ,1 ,2 ,...k-2 ,k,k+1,...n-1
n-k,n-k+1,n-k+2,...n-k+k-2(=n-2),0,1 ,...n-k-1
这样问题就变成了J(n-1)谁能活下来,通过下标变换(约瑟夫很多变种问题都要求进行下标变换,所以这个是基础,应该要理解清楚),就能知道J(n)谁能活下来:J(n)=(J(n-1)+k)%n;
有了这个式子,我就不想多说了。J(1)=0(这个很简单),然后没有然后了。。
代码附上:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<iomanip> 4 #include<algorithm> 5 #include<cstring> 6 #include<string> 7 #include<bitset> 8 #include<queue> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #define rep(i,n,m) for(int i=(n);i<=(m);++i) 13 #define re1(i,n) rep(i,1,n) 14 #define re0(i,n) rep(i,0,n) 15 #define RE(a) ((a)*(a)) 16 #define SIZE(a) (int((a).size())) 17 //count distance 不能用哦,已经定义了。 18 typedef long long ll; 19 using namespace std; 20 const int maxnum=int(1e4)+1; 21 const int maxint=2147483647; 22 int J[maxnum]; 23 template<class T> 24 void show(T &a,int n,int m){ 25 rep(i,n,m){ 26 cout<<setw(6)<<a[i]; 27 } 28 cout<<endl; 29 } 30 int Josephus(int n,int k){ 31 int &ans=J[n]; 32 if(ans!=-1) 33 return ans; 34 if(n==1) 35 return ans=0; 36 return ans = (Josephus(n-1,k)+k) % n; 37 } 38 int get(int ans,int k,int m,int n){ 39 return (ans+n-(k%n-m))%n+1; 40 } 41 int main(){ 42 int n,k,m; 43 while(~scanf("%d%d%d",&n,&k,&m)){ 44 if(n==k && k==m && m==0) 45 break; 46 re1(u,n) 47 J[u]=-1; 48 printf("%d\n",get(Josephus(n,k),k,m,n)); 49 } 50 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<iomanip> 4 #include<algorithm> 5 #include<cstring> 6 #include<string> 7 #include<bitset> 8 #include<queue> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #define rep(i,n,m) for(int i=(n);i<=(m);++i) 13 #define re1(i,n) rep(i,1,n) 14 #define re0(i,n) rep(i,0,n) 15 #define RE(a) ((a)*(a)) 16 #define SIZE(a) (int((a).size())) 17 //count distance 不能用哦,已经定义了。 18 typedef long long ll; 19 using namespace std; 20 const int maxnum=150+1; 21 const int maxnum2=int(1e4)+1; 22 const int maxint=2147483647; 23 int J[maxnum][maxnum2]; 24 template<class T> 25 void show(T &a,int n,int m){ 26 rep(i,n,m){ 27 cout<<setw(6)<<a[i]; 28 } 29 cout<<endl; 30 } 31 int Josephus(int n,int k){ 32 int &ans=J[n][k]; 33 if(ans!=-1) 34 return ans; 35 if(n==1) 36 return ans=0; 37 return ans = (Josephus(n-1,k)+k)%n; 38 } 39 int fix(int ans){ 40 return ans+2; 41 } 42 int main(){ 43 int n; 44 re1(u,maxnum-1)re1(w,maxnum2-1) 45 J[u][w]=-1; 46 while(~scanf("%d",&n)){ 47 if(n==0) 48 break; 49 int k=1; 50 while(fix(Josephus(n-1,k))!=2){ 51 k++; 52 } 53 printf("%d\n",k); 54 } 55 }