习题8-4 报数 (20 分)

报数游戏是这样的:有n个人围成一圈,按顺序从1到n编好号。从第一个人开始报数,报到m(<n)的人退出圈子;下一个人从1开始报数,报到m的人退出圈子。如此下去,直到留下最后一个人。

本题要求编写函数,给出每个人的退出顺序编号。

函数接口定义:

void CountOff( int n, int m, int out[] );

其中n是初始人数;m是游戏规定的退出位次(保证为小于n的正整数)。函数CountOff将每个人的退出顺序编号存在数组out[]中。因为C语言数组下标是从0开始的,所以第i个位置上的人是第out[i-1]个退出的。

裁判测试程序样例:

#include <stdio.h>
#define MAXN 20

void CountOff( int n, int m, int out[] );

int main()
{
    
    
    int out[MAXN], n, m;
    int i;

    scanf("%d %d", &n, &m);
    CountOff( n, m, out );   
    for ( i = 0; i < n; i++ )
        printf("%d ", out[i]);
    printf("\n");

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

11 3

输出样例:

4 10 1 7 5 2 11 9 3 6 8 

题解:

/*每个人的退出顺序编号:就是这个人是第几个退出的*/
void CountOff( int n, int m, int out[] )
{
    
    
	int a [MAXN] = {
    
    0}; //定义a数组,存放初始人数
	int b [MAXN] = {
    
    0}; //定义b数组,存放每个人的退出顺序编号
	int i; //循环变量
	int j = 1; //退出顺序(第几个退出)的变量,初值为1
    int cnt = 0; //计数器,判断该人是不是要退出
	int sum = 0; //退出的总人数
	
    /*给数组a赋值,存放初始人数*/
	for (i = 1; i <= n; i++) // 下标i从1开始,a[1]就表示1 a[2]就表示2
	{
    
    
		a [i] = i;
	}
	
	while (sum < n) //当退出总人数小于总人数时循环
	{
    
    
        /*遍历查找,计数器cnt累加,到m就赋值为-1该人退出,把该人赋值给数组b*/
		for (i = 1; i <= n; i++) //遍历
		{
    
    
			if (a [i] != -1) //如果数组a[i]不等于-1(-1表示已退出)就计数器cnt加一
			{
    
    
				cnt++ ;
			} 
			if (cnt == m) //当计数器等于m时:
			{
    
    
				a [i] = -1; //把该数赋值为-1
				cnt = 0; //计数器清零,为下轮做准备
				b [i] = j; //把该人赋值退出顺序就是编号(详细请看底部的草稿)
                /*这里的b[i] = j也可以写成out[i - 1] = j这样可以少定义一个数组还有省略下面的循环*/

				j++; //推出顺序变量加一
                sum++; //推出总人数加一	
			}
		}
	}
    /*赋值给out数组*/
	for (i = 1; i <= n; i++)
	{
    
    
		out[i - 1] = b [i];
	} 
	
}
/*草稿:横排是i变量,竖排是j变量
1 2 3 4 5 6  i
            1
         2
                3    j
   4
      5
6    
546231 每个人的退出顺序(5号是第一个退出,紧接着是46231)

645213每个人的退出顺序编号(1号是第6个退出的,2号是第4个退出,以此类推)


*/

猜你喜欢

转载自blog.csdn.net/qq_44715943/article/details/114655277