• 1. 约瑟夫问题


    题目(要求用循环链表实现)

    约瑟夫问题是一个经典的问题。已知n个人(不妨分别以编号1,2,3,…,n 代表 )围坐在一张圆桌周围,从编号为 k 的人开始,从1开始顺时针报数1, 2, 3, ...,顺时针数到m 的那个人,出列并输出。然后从出列的下一个人开始,从1开始继续顺时针报数,数到m的那个人,出列并输出,…依此重复下去,直到圆桌周围的人全部出列。

    输入:n, k, m

    输出:按照出列的顺序依次输出出列人的编号,编号中间相隔一个空格,每10个编号为一行。

    非法输入的对应输出如下

    a)

    输入::nkm任一个小于1
    输出:n,m,k must bigger than 0.

    b)

    输入:k>n

    输出:k should not bigger than n.

    例:

    输入:9,3,2

    输出:4 6 8 1 3 7 2 9 5


    注意事项

    1. 创建循环链表时,需要将链表的首尾相连,形成循环。
    2. 在每次出列后,要及时释放被删除节点的内存空间,避免内存泄漏问题。
    3. 在输出结果时,需要根据出列人数的情况进行换行和空格的处理,确保输出结果符合题目要求。
       

    C++完整代码(含注释)

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. struct ListNode {
    6. int val;
    7. ListNode* next;
    8. ListNode(int x) : val(x), next(NULL) {}
    9. };
    10. int main() {
    11. int n, k, m;
    12. scanf("%d%*c%d%*c%d", &n, &k, &m);
    13. // 检查输入的合法性
    14. if (n < 1 || k < 1 || m < 1) {
    15. cout << "n,m,k must bigger than 0." << endl;
    16. return 0;
    17. }
    18. if (k > n) {
    19. cout << "k should not bigger than n." << endl;
    20. return 0;
    21. }
    22. // 创建循环链表
    23. ListNode* head = new ListNode(1); // 创建链表的头节点
    24. ListNode* cur = head; // 当前节点指针
    25. for (int i = 2; i <= n; i++) { // 创建链表的其他节点
    26. cur->next = new ListNode(i);
    27. cur = cur->next;
    28. }
    29. cur->next = head; // 将链表首尾相连,形成循环链表
    30. // 将cur指针移动到编号为k的节点
    31. for (int i = 0; i < k - 1; i++) {
    32. head = head->next;
    33. }
    34. int count = 0; // 记录出列的人数
    35. // 开始报数并出列
    36. while (n) { // 当还有人没有出列时
    37. if (m > 1) { // 数到m的前一个节点
    38. for (int i = 0; i < m - 2; i++) {
    39. head = head->next;
    40. }
    41. // 出列并记录编号
    42. ListNode* temp = head->next;
    43. cout << temp->val; // 输出出列人的编号
    44. head->next = temp->next; // 删除出列的节点
    45. head = head->next; // 移动cur指针到下一个节点
    46. delete temp; // 释放被删除节点的内存空间
    47. n--; // 更新剩余人数
    48. count++; // 更新出列人数
    49. }
    50. else { // m等于1时,直接将cur指针指向下一个节点
    51. cout << head->val; // 输出出列人的编号
    52. head = head->next; // 移动cur指针到下一个节点
    53. n--; // 更新剩余人数
    54. }
    55. // 根据出列人数的情况输出结果
    56. if (n == 0 && count % 10 != 0) {
    57. cout << endl; // 所有人都出列且最后一行不满10个编号,换行
    58. }
    59. else if (count % 10 == 0) {
    60. cout << endl; // 出列人数达到10的倍数,换行
    61. }
    62. else {
    63. cout << " "; // 输出编号之间的空格
    64. }
    65. }
    66. return 0;
    67. }

  • 相关阅读:
    Flink操作——状态与容错
    探索ABP的EventHub解决方案
    UDP 协议详解
    今天,该让 python 上个热门
    基于智慧杆的铁路站台两端入侵监测告警方案
    真是学到了!——《Nginx的几个常用配置和技巧》
    第三章 MATLAB的使用
    win11下配置ftp
    Linux 文件与目录管理
    Mac上安装OpenLDAP服务器详细教程(Homebrew安装和自带的ldap)
  • 原文地址:https://blog.csdn.net/m0_74200772/article/details/132830597