[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(这个很简单),然后没有然后了。。

代码附上:

《[Josephus(约瑟夫环)] poj3517poj2244》
《[Josephus(约瑟夫环)] poj3517poj2244》
3517

 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 }

《[Josephus(约瑟夫环)] poj3517poj2244》
《[Josephus(约瑟夫环)] poj3517poj2244》
2244

 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 }

 

    原文作者:GGGin
    原文地址: https://www.cnblogs.com/gggin/archive/2012/12/23/2830005.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞