约瑟夫环
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了约瑟夫环相关的知识,希望对你有一定的参考价值。
问题一:输出打印顺序
题目链接:九度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 }
问题二: 从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
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 }
以上是关于约瑟夫环的主要内容,如果未能解决你的问题,请参考以下文章