n个人围成圈报数游戏
n个人围成圈报数游戏
Description
有n个人围成一圈,顺序排号。从第一人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
Input
一行,一个数n。
Output
输出最后留下来的人的序号。
Sample Input 1
40
Sample Output 1
28
一、前期:一头雾水
看到这个题目时,我先在草稿纸上画了画,感觉写起来可能有点难度。
但是,真正打开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.“围成一圈”:可以通过设置一个变量,在循环到第一个值时继续++就行。