约瑟夫环

约瑟夫环定义

问题一:输出打印顺序

题目链接:九度1188

http://ac.jobdu.com/problem.php?pid=1188

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <list>
 6 using namespace std;
 7 const int Max = 3000 + 10;
 8 int a[Max],flag[Max];
 9 int main()
10 {
11     int n,k;
12     while(scanf("%d%d", &n, &k) != EOF)
13     {
14         a[0] = n;
15         for(int i = 1; i < n; i++)
16         {
17             a[i] = i;
18         }
19         memset(flag, 1, sizeof(flag));
20         int m = n,i = 0;
21         int ans;
22         while(m >= 1)
23         {
24             int num = 0;
25             while(num < k)
26             {
27                 while(flag[ (i + 1) % n] == 0)
28                 {
29                     i = (i + 1) % n; //已经选完了就跳过
30                 }
31                 num++;
32                 i = (i + 1) % n;
33             }
34             ans = a[i];
35             flag[i] = 0;
36             m--;
37             if(m == 0) //最后一个单独输出
38                 break;
39             printf("%d ", ans);
40         }
41         printf("%d\n", ans);
42     }
43     return 0;
44 }
View Code

 

问题二: 从0开始,求结束是几个

递推公式: f [ n ] = ( f[ n - 1] + k ) % n

可以这么想,从0要选k个,k - 1个被毙掉,所以形成了一个新的环 k , k + 1, k  + 2, ... k - 2,然后从k开始,而此时的k 也可以看做 0 ,k + 1就是1,最后一项是 n - 2,此时只n - 1个人了,如果此时求解出来的最后剩下的那个胜利的人为 x ,那么 根据这个 k <-> 0 ; k + 1 < - > 1 ... k - 2 < - > n - 2 ; 对应关系 就可以看出上一个状态的 x' = (x + k) % n

例题:九度1356

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     int n,k;
10     while(scanf("%d", &n) != EOF && n)
11     {
12         scanf("%d", &k);
13         int f = 0;  // 因为就一个的时候就是对应的为0的项
14         for(int i = 2; i <= n; i++)
15             f = ( f + k ) % i;
16         printf("%d\n", f + 1);
17     }
18     return 0;
19 }
View Code

 

你可能感兴趣的:(约瑟夫环)