约瑟夫环问题(数组法)c语言实现

yizhihongxing

约瑟夫环问题(数组法)C语言实现

问题描述

有 $n$ 个人围成一圈,第 $m$ 个人开始报数,报到 $m$ 的人出圈,然后从出圈的下一个人开始继续报数,直到圈中只剩下一人。求出该人的编号。

解法思路

采用数组法解决约瑟夫环问题,主要的思路是:构建一个大小为 $n$ 的数组,来表示 $n$ 个人在约瑟夫环中的位置,将这些位置依次删除,直到只有一个人为止。

具体的步骤如下:

  1. 定义一个大小为 $n$ 的数组 a,并初始化数组元素为 $1$ 表示这些人都还在约瑟夫环中。

  2. 定义一个变量 step,用来表示报数的步长。

  3. 定义一个变量 count,用来表示当前数到的位置。

  4. 定义一个变量 iIndex,用于记录出圈人的编号。

  5. 从第 $m$ 个人开始报数,即将变量 count 的初始值设置为 $m - 1$。

  6. 当数组 a 中的元素个数不为 $1$ 时,进行如下循环:

  7. count 的值加上 step - 1,即数到第 $m$ 个人所在的位置,再判断该位置是否为 $1$,如果是 $1$,则表示该人还在约瑟夫环中,继续往前数;如果不是 $1$,说明该人已经出圈,需要继续数,直到数到一个还在约瑟夫环中的人为止。

  8. 当找到下一个还在约瑟夫环中的人时,将其所在位置的数组元素置为 $0$,表示该人已经出圈。

  9. 记录该人的编号,即 iIndex 变量的值为当前所在位置 $+ 1$,因为数组下标从 $0$ 开始,编号从 $1$ 开始。

  10. count 变量加 $1$,表示从下一个人开始重新计数。

  11. 当数组 a 中的元素个数为 $1$ 时,剩下的那个人就是最后留下的人,输出其编号即可。

代码实现

以下是用 C 语言实现约瑟夫环问题(数组法)的完整程序代码,其中包括了两个示例,分别对应了题目中的两个例子:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n = 5; // 5个人
    int m = 3; // 从第3个人开始报数
    int step = 2; // 报数步长为2

    // 初始化人员位置数组
    int* a = (int*)malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) {
        a[i] = 1;
    }

    // 初始化变量
    int count = 0;
    int iIndex = -1;

    // 开始报数
    while (1) {
        for (int i = 0; i < n; i++) {
            if (a[i] == 1) {
                count++;
                if (count == m) {
                    a[i] = 0; // 当前位置的人出圈
                    iIndex = i + 1; // 出圈人的编号
                    count = 0; // 重新开始报数
                }
            }
        }

        int iLeft = 0;
        for (int i = 0; i < n; i++) {
            if (a[i] == 1) {
                iLeft++;
            }
        }

        if (iLeft == 1) {
            break; // 数组中只剩下一个人了
        }
    }

    printf("当 n = %d, m = %d, step = %d 时,最后出圈的人的编号是:%d\n", n, m, step, iIndex);
    free(a);

    n = 3; // 3个人
    m = 2; // 从第2个人开始报数
    step = 3; // 报数步长为3

    // 初始化人员位置数组
    a = (int*)malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) {
        a[i] = 1;
    }

    // 初始化变量
    count = 0;
    iIndex = -1;

    // 开始报数
    while (1) {
        for (int i = 0; i < n; i++) {
            if (a[i] == 1) {
                count++;
                if (count == m) {
                    a[i] = 0; // 当前位置的人出圈
                    iIndex = i + 1; // 出圈人的编号
                    count = 0; // 重新开始报数
                }
            }
        }

        int iLeft = 0;
        for (int i = 0; i < n; i++) {
            if (a[i] == 1) {
                iLeft++;
            }
        }

        if (iLeft == 1) {
            break; // 数组中只剩下一个人了
        }
    }

    printf("当 n = %d, m = %d, step = %d 时,最后出圈的人的编号是:%d\n", n, m, step, iIndex);
    free(a);

    return 0;
}

示例说明

第一个示例中,有 $5$ 个人,从第 $3$ 个人开始报数,报数步长为 $2$,最后出圈的人的编号为 $5$。

第二个示例中,有 $3$ 个人,从第 $2$ 个人开始报数,报数步长为 $3$,最后出圈的人的编号为 $3$。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:约瑟夫环问题(数组法)c语言实现 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • JSON在PHP中的应用介绍

    下面是“JSON在PHP中的应用介绍”的完整攻略。 什么是JSON JSON(JavaScript Object Notation),是一种轻量级的数据交换格式。它以易于读写的文本格式为基础,被用来传输和储存数据。 JSON数据可以用代码轻松地从不同的语言传递和访问,例如从PHP中传递JSON数据给JavaScript代码,从JavaScript代码中传递J…

    C 2023年5月23日
    00
  • C语言比较函数指针

    下面我来详细讲解一下“C语言比较函数指针”的使用攻略。 简介 在C语言中,我们常常需要对数据进行排序、查找等操作,而这些操作通常需要用到比较函数。比较函数指的是能够比较两个元素大小的函数,一般格式为: int compare(const void *a, const void *b); 其中,a和b是待比较的两个元素,函数应该根据需要返回一个整数值: 若a&…

    C 2023年5月9日
    00
  • VC中CWinThread类以及和createthread API的区别分析

    VC中CWinThread类是MFC(Microsoft Foundation Class)中提供的一个类,用于创建和管理Windows应用程序中的线程。这个类可以方便的管理线程的运行、暂停、停止和同步等操作,可以大大提高程序的可读性和可维护性。 与CWinThread类相比,CreateThread API函数则是Windows API中用于创建线程的函数…

    C 2023年5月22日
    00
  • C++学习进阶篇之类大小计算和this指针

    C++学习进阶篇之类大小计算和this指针 类大小计算 在C++中,类的大小计算是非常重要的。一个类的大小包括它所占用的存储空间以及它所包含的成员变量所占用的存储空间。在计算类的大小时,通过以下几个方面来确定: 子对象的大小 虚拟函数表指针的大小 数据成员的大小 子对象的大小 类可能会继承其他类,所以需要考虑子对象的大小。子对象的大小实际上是在编译时计算的,…

    C 2023年5月30日
    00
  • C语言之整数划分问题(递归法)实例代码

    C语言之整数划分问题(递归法)实例代码是一篇介绍整数划分问题及其递归解法的文章,并提供了C语言代码实现。下面将详细讲解这篇文章的内容。 整数划分问题简介 首先,文章介绍了整数划分问题的背景和定义。整数划分问题的定义是:将一个正整数$n$划分成不超过$n$个正整数的和,每个划分方案中的数都必须不小于$1$,且不考虑顺序。例如,对于$4$这个数字,可以划分为以下…

    C 2023年5月24日
    00
  • C语言用指针支持栈

    C语言用指针支持栈的完整使用攻略 栈是一种常见的数据结构,在C语言中可以使用指针来支持栈。下面是用指针实现栈的完整使用攻略: 数据结构 栈是一种后进先出(LIFO)的数据结构,可以用数组或链表实现。这里我们使用数组实现栈。 定义栈结构体: #define MAXSIZE 10 // 栈的容量 typedef struct stack { int data[M…

    C 2023年5月9日
    00
  • C语言递归实现扫雷游戏

    C语言递归实现扫雷游戏攻略 什么是递归? 递归是指函数调用自身的过程。递归函数是这样一种函数,它的重点在于在某个条件下调用自己,通常缩短问题的规模。比如说,在解决扫雷游戏的过程中,可能需要递归函数来处理周围方块是否可以揭开、是否需要继续递归等问题。 扫雷游戏的实现 游戏规则 扫雷游戏以一个矩形方格作为游戏场地,其中有一些格子中埋藏着地雷。游戏开始时,每个格子…

    C 2023年5月23日
    00
  • C语言编写获取Linux本地目录及本机信息的小程序实例

    下面是详细讲解“C语言编写获取Linux本地目录及本机信息的小程序实例”的完整攻略: 1. 程序的概要 该程序主要通过C语言来获取Linux本地目录以及本机信息,包括以下功能: 获取当前程序所在目录 获取主机名和IP地址 获取系统空闲内存大小 获取磁盘剩余空间大小 获取系统时间 2. 程序实现步骤 2.1 获取当前程序所在目录 要获取当前程序所在目录,可以使…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部