数组实现

  1. //约瑟夫环问题,数组实现,从1开始编号
  2. #include <iostream>
  3. using namespace std;
  4. int a[110] = {0};
  5. int main() {
  6. int n,m;
  7. int cnt = 0, i=0,k=0; //cnt表示目前出局的人数
  8. cin >> n >> m;
  9. while(cnt != n) //当前出局的人数小于n
  10. {
  11. i++;
  12. if(i>n) i = 1;
  13. if(a[i] == 0)
  14. {
  15. k++;
  16. if(k == m)
  17. {
  18. a[i] = 1;
  19. k = 0; //方便下一个人重新从1开始报数
  20. cnt ++ ;
  21. cout << i << " ";
  22. }
  23. }
  24. }
  25. return 0;
  26. }

循环链表实现

image.png

  1. //约瑟夫环链表解法
  2. #include <iostream>
  3. using namespace std;
  4. typedef struct node{
  5. int data;
  6. struct node *next;
  7. }Node;
  8. void ysflb(int n, int k) // 总共有n个人,报到数字为k的人出局。
  9. {
  10. //创建循环链表
  11. Node *head = NULL, *p = NULL, *r = NULL;
  12. head = (Node *)malloc(sizeof(Node)); //申请空间
  13. if(head == NULL) //如果空间申请失败
  14. {
  15. cout << "Memory Failed!";
  16. return;
  17. }
  18. head -> data = 0;
  19. head -> next = NULL;
  20. p = head;
  21. //循环链表创建,使用尾插法
  22. for(int i=1;i<n;i++)
  23. {
  24. r = (Node *)malloc(sizeof(Node));
  25. r -> data = i;
  26. r -> next = NULL;
  27. p -> next = r;
  28. p = r;
  29. }
  30. p -> next = head;
  31. p = head;
  32. //约瑟夫环模拟
  33. while(p -> next != p)
  34. {
  35. for(int i=1;i<k;i++)
  36. {
  37. r = p; //保存前一个节点
  38. p = p -> next; //p为出局的节点
  39. }
  40. cout << p->data << ' ';
  41. r -> next = p -> next; //删除p节点
  42. p = p->next;
  43. }
  44. cout << endl << p->data;
  45. }
  46. int main() {
  47. //int n,k;
  48. //cin >> n >> k;
  49. ysflb(10,3);
  50. return 0;
  51. }

递归求解

image.png

  1. #include <iostream>
  2. using namespace std;
  3. int ysf(int n,int k, int i)
  4. //设f(n,k,i)为n个人的环,报数为k,第i个人出环的编号,
  5. //则f(10,3,10)是我们想要的结果
  6. {
  7. if(i == 1)
  8. return (n+k-1)%n;
  9. else
  10. return (ysf(n-1,k,i-1)+k)%n;
  11. }
  12. int main() {
  13. int n,m;
  14. cin >> n >> m;
  15. for(int i = 1; i<=n;i++)
  16. printf("第%d次出环:%d\n",i,ysf(n,m,i));
  17. return 0;
  18. }