c语言实现淘汰游戏。

能不能帮我注释一下这些语句都是什么意思啊,看不懂,这个在网上找的,题目是一共有n个人围成一圈,从1~n编号,第一轮第个人开始,报到设定的m时,终止退出,接着退出的人后面的那个人从1开始报,直到m又退出。



#include <stdio.h>
#define MAXN 20
 
void CountOff(int n,int m,int out[]);
int main()
{
    int out[MAXN],n,m;
    int i;
    printf("请输入参与的人数n:"); 
    scanf("%d",&n);
    printf("请输入选定的数字m:");
    scanf("%d",&m);
    CountOff(n,m,out);   
    for(i=0;i<n;i++)
        printf("%d ", out[i]);
    
    return 0;
}
 
void CountOff(int n,int m,int out[])
{
    int flag=n;//可以判断 n次 
    int i=0,j=1,num=0,a[MAXN];
    for(i=0;i<n;i++)
    {
        a[i]=i+1;
    }
    while(flag!=0)
    {
        for(i=0;i<n;i++)
        {
            if(a[i]!=0)
            {
                num++;
                if(num==m)
                {
                    a[i]=0;
                    out[i]=j;
                    j++;
                    flag--;
                    num=0;    
                }    
            }    
        }
    }
}

这段代码是一个约瑟夫环问题的解决方案。约瑟夫环是一个数学问题,描述了一群人围成一个圆圈,从某个位置开始报数,每报数到一个指定的数字m,该位置的人就出局,然后从下一个位置重新开始报数,直到剩下最后一个人。

这段代码中的CountOff函数实现了约瑟夫环的计算过程。它接受三个参数:参与的人数n,选定的数字m,以及一个用于保存出局顺序的数组out[]。

在函数内部,首先创建一个数组a[],用于表示每个人的状态(1表示还在游戏中,0表示已出局)。然后使用一个while循环来进行游戏的计算,直到所有人都出局为止。

在每一轮循环中,使用一个for循环遍历数组a[],找到第一个仍然在游戏中的人。然后使用一个计数器num来记录报数的次数,当num等于m时,表示该人出局,将其标记为0,并将其出局的顺序j保存到数组out[]中。然后递增J

最后,在主函数中,用户输入参与的人数n和选定的数字m,然后调用CountOff函数进行计算,并将结果打印出来。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7666268
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。
  • 除此之外, 这篇博客: C语言指针练习中的 1、有一个字符串,包含n个字符。写一函数,将此字符串中从第m个字符开始的全部字符复制成为另一个字符串;(复制操作在子函数中实现,并用指针传递); 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:
    #include <stdio.h>
    
    /* 有一个字符串,包含n个字符。写一函数,将此字符串中从第m个字符开始的全部字符
    复制成为另一个字符串;(复制操作在子函数中实现,并用指针传递); */
    
    int main(void)
    {
        int n,m;
        char string[100];
        printf("输入一个数n:");  //n是字符串一共的个数
        scanf("%d",&n);
        printf("输入一串字符 :");
        scanf("%s",string);
        printf("输入一个数m:");  //m是需要移动赋值的字符串数
        scanf("%d",&m);
        printf("结果为:");
        copy(string,n,m);
        return 0;
    }
    void copy(char* str, int n, int m)
    {
        int i,j;
        char string[100];
        char *p = string;
        i = m-1;
        j = 0;
        str = str + i;               //从m-1个位置开始赋值给一个新的字符数组
        for( ;i < n; i++,j++)
        {
            *(p+j) = *(str++);
            printf("%c",*(p+j));
        }
    }
    
  • 以下回答来自chatgpt:

    解释: - #include<stdio.h>#include<stdbool.h> 分别包含了输入/输出函数和C语言中布尔类型的定义。 - int n,m,i,sum,del,count,flag; 定义了7个整型变量:n,m,i,sum,del,count和flag。 - int a[500]; 定义了一个整型数组a,长度为500。 - bool b[500]; 定义了一个布尔型数组b,长度为500。 - while(2==scanf("%d,%d",&n,&m)) 循环读入两个整数n和m,直到读入的个数不为2(即读入结束)。 - for(i=0;i<n;i++) a[i]=i+1; 循环将1~n中的数保存到数组a中。 - for(i=0;i<500;i++) b[i]=false; 循环将数组b中所有元素都设置为false,表示每个人都没被淘汰。 - count=n; 初始化未淘汰的人数为n。 - flag=true; 初始化标记为true,表示这是第一轮游戏。 - while(count) 只要还有人未淘汰,就循环进行游戏。 - if(flag) i=del; 如果是第一轮游戏,从del位置开始计数。 - else 如果不是第一轮游戏,从i-1位置开始计数。 - if(i==-1) i=n-1; 如果i小于0了,则从数组a的末尾位置开始计数。 - if(!b[i]) 如果这个编号的人没有被淘汰(即b[i]为false)。 - sum++; 对sum进行自增1操作,表示报数的次数增加1。 - if(sum==m) 如果报数的次数等于m。 - printf("%d,",a[i]); 输出编号a[i]。 - b[i]=true; 将这个编号的人标记为已经淘汰(即b[i]设为true)。 - del=i; 记录上一轮游戏淘汰的位置。 - count--; 未淘汰的人数减1。 - sum=0; 重新设置sum为0,开始下一轮报数。 - flag=false; 将标记设为false,表示这不是第一轮游戏。 - return 0; 程序结束。

    代码的作用是:实现一个淘汰游戏,输入游戏中可用的人数n和每次淘汰的步长m后,从1~n开始报数,每数到m便淘汰报到的那个人,输出淘汰的人的编号,直到所有人都被淘汰为止。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^