算法训练 - 筛选号码 (有n个人围成一圈,顺序排号(编号为1到n)。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子。从下一个人开始继续报数,直到剩下最后一个人,游戏结束。)

问题描述

有n个人围成一圈,顺序排号(编号为1到n)。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子。从下一个人开始继续报数,直到剩下最后一个人,游戏结束。
  问最后留下的是原来第几号的那位。
  举个例子,8个人围成一圈:
  1 2 3 4 5 6 7 8
  第1次报数之后,3退出,剩下:
  1 2 4 5 6 7 8 (现在从4开始报数)
  第2次报数之后,6退出,剩下:
  1 2 4 5 7 8 (现在从7开始报数)
  第3次报数之后,1退出,剩下:
  2 4 5 7 8 (现在从2开始报数)
  第4次报数之后,5退出,剩下:
  2 4 7 8 (现在从7开始报数)
  第5次报数之后,2退出,剩下:
  4 7 8 (现在从4开始报数)
  第6次报数之后,8退出,剩下:
  4 7 (现在从4开始报数)
  最后一次报数之后,4退出,剩下:
  7.
  所以,最后留下来的人编号是7。
输入格式
  一个正整数n,(1<n<10000)
输出格式
  一个正整数,最后留下来的那个人的编号。
例子

样例输入
8
样例输出
7

跟前几天写那个狡猾的老鼠那道题99%一样,代码放上了,就是巧妙的模拟就是了。

#include <stdio.h>
#define m 3
int main ()
{
    
    
	int n,n1,step,i;
	scanf("%d",&n);
	int a[n];
	for(i=0;i<n;i++)
		a[i]=0;
	n1=n;
	i=0;
	while(n1>1)
	{
    
    
		step=m;
		while(1)
		{
    
    
			i++; 
			if(i==n)
				i=0;
			if(a[i]==0)
				step--;
			if(step==0)
				break;
		 } 
		a[i]=1;
		n1--;
	}
	for(i=0;i<n;i++)
	{
    
    
		if(a[i]==0)
			printf("%d\n",i);
	}
	return 0; 
}

在其他博主那看到另一种表达,也很不错呢:
他的思路:定义一维数组, 数组下标表示人的编号, 值表示是否出局(1为出局), 先将数组元素全部初始化为0, 然后定义两个整型变量 num 表示人的编号和 count 其所报的数(i 在0~2循环, 0即表示报数为3,则出局),再定义一个整型变量left记录剩余人数, 剩余1人时退出循环。此人为胜者并输出其编号。

#include <stdio.h>

int main(){
    
    
    int a[10000] = {
    
    0};
    int sum;  //总人数 
    int num, count, left;
    scanf("%d", &sum);
    left = sum;
    for(num=0,count=1; ; num=(num+1)%sum){
    
    
        if(a[num] == 1)  //若此人出局则继续找下一位未出局的人 
            continue;
        if(count==0){
    
       //若此人报数为 0 则此人出局 
            a[num] = 1;
            left--;
            if(left == 1)
                break;
        }
        count=(count+1)%3;
    }
    for(num=0; num < sum; num++)  //在数组中找到唯一未出局的人 
        if(a[num]==0)break;
    printf("%d", num+1);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45281807/article/details/104525993