n个人围成圈报数游戏

发布时间 2023-12-02 20:28:16作者: 20231420

n个人围成圈报数游戏

n个人围成圈报数游戏

Description
有n个人围成一圈,顺序排号。从第一人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。

Input
一行,一个数n。

Output
输出最后留下来的人的序号。

Sample Input 1 
40

Sample Output 1
28

来源:CP1266 n个人围成圈报数游戏(难度:中等)

一、前期:一头雾水

看到这个题目时,我先在草稿纸上画了画,感觉写起来可能有点难度。
但是,真正打开Clode Blocks时,我才真正面对了它。
看着“Hello World”,我想开始写,却发现无从下手:
怎么让报数3的人走开?
想不出来这个问题,我连一个“int”都打不出来。
这个问题难住了我。

二、中期:希望渺茫

循环报数,已经走开的人不参与接下来的报数。
我感觉这就是这个题的难点。
想出来,就能做出来;想不出,就做不出来。
我想了十分钟,仍旧是找不到方向。
我想过上网查询,但却又不甘心。
这时,我想到一个理论:

做不出来一道题时,可以先放一放,先做后面的题,做着做着前面的那个题也就能做出来了。

于是我先去做了它后面的那道题:CP1487用指针实现数据交换(难度:简单)
呃……四五行的代码……
再后面,就不是指针的题了。
于是我又回到了这道题。

三、后期:峰回路转

其实我还是没有做出来。
并不存在说,做一道简单题后,就能做出中等题的说法。
于是我去吃了个饭。
吃完饭回来,灵光一闪……不对。
没有灵光。
我还是只能在草稿本上写写画画,希冀那一刹那的灵光。
它来了。
没有来由地,我突然想到:如果把报数3的数字赋值为0,会怎么样?
这就是正解。

点击查看代码
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i,j=0,n,shu,shuzu[100];
    scanf("%d",&n);
    shu=n;
    for(i=0; i<n; i++)
    {
        shuzu[i]=i+1;
    }
    while(shu>1)
    {
        for(i=0; i<n; i++)
        {
            if(shuzu[i]!=0)
            {
                j++;
                j=j%3;
            }
            if(j==0)
            {
                shuzu[i]=0;
            }
        }
        shu=0;
        for(i=0; i<n; i++)
        {
            if(shuzu[i]!=0)
                shu++;
        }
    }
    for(i=0; i<n; i++)
    {
        if(shuzu[i]!=0)
            printf("%d\n",shuzu[i]);
    }
    return 0;
}

但是啊,这里面并没有用到指针。

四、尾声

我终究是做了出来。
指针嘛,程序都出来了,插进去还不简单?
——————————
有点烂尾……
可能是我太菜了,但我确实花了很长时间才想出来0这个操作……
另外,前面的小故事,看看就好,不要笑我(* /ω\*)
下面是思考与总结。

五、回归问题本身

在做出来后,我上网查询了一下这个问题,它是C语言经典例题(还有名字“约瑟夫问题/约瑟夫环”),并且网上有很多讲解,也有多种方法。
回忆我做这道题时的想法,发现其实赋值0也可以改为赋值-1之类的,只要赋同一个值,非正数就行。
总之,通过这道题目,我领悟到了两个小妙招:
1.“离开/退出”:可以通过赋值0/负数;
2.“围成一圈”:可以通过设置一个变量,在循环到第一个值时继续++就行。