c语言报数问题程序,转圈报数问题(C语言):有n个人围成一圈,顺序排号……...

问题描述:

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

题目分析:

这道题目是我们在日常生活中也能经常见到的一种报数小游戏。首先我们先分析一下游戏的核心——轮流报数 这个过程的本质是什么呢?我们分析一下游戏的过程。

我们先举一个实例:假如有5个人 分别为ABCDE

第一轮:A报1 B报2 C报3(被淘汰) D报1 E报2

第二轮:A报3(被淘汰)B报1 C(已被淘汰)D报2 E报3(淘汰)

第三轮:A(已被淘汰)B报1 C(已被淘汰)D报2 E(已被淘汰)

第四轮:A(已被淘汰)B报3(被淘汰)仅剩一人游戏结束 D获胜

总结一下就是:游戏开始,所有人依次报数,报到三的都退出。所有剩下的人继续报数。一轮结束后 第一个人接着上一轮继续报数,以此类推,直到只剩下一个人。

那么主要的动作有两个:

不断重复地1~3报数 但要跳过已被淘汰的人 且 一轮结束后 继续接着上一轮的结尾的数字

将报到3的人移出

那么如何用C语言实现这两点呢?

第二个很好解决 我们就用最简单的建立对应长度的数组 用1表示仍在场上 0表示已被淘汰。

第一个过程想要用C语言来实现就要模拟出不断1~3的循环 而且还能够不间断的在不同轮间衔接。

这样乍一看没有任何思路。那么怎么样能将问题简化一下,更加直观的表达出来呢?

1~3循环报数,报到3的淘汰的本质和从1开始报数,报到三的倍数淘汰的本质是一样的:

1 2 3(淘汰)1 2 3(淘汰)1 2 3(淘汰)

1 2 3(淘汰)4 5 6(淘汰)7 8 9(淘汰)

而且这样顺序的继续也够方便轮与轮之间的衔接 也就是不需要记住上一轮最后一个人报的是什么数字,继续一直向下报即可。

到这里 这道题的大体思路便清晰了,只要将已被淘汰的跳过等几个细节实现一下即可实现这道题目。

下面是展示版程序的代码:可以显示每一轮的具体情况(谁在报数 谁被淘汰)如不需要 将printf去掉即可。

在解决这样较复杂的问题时,先把程序写成这种能够展示过程的样子,个人认为更有利于debug和看出自己考虑不足之处。

#include

int main()

{

int a[120]={0}; //建立数组

int i,n,k,j,final_num,sum;

printf("Please enter n(<120):"); //确定参与人数 这里图方便就直接将数组定为了120人以下 也可用动态数组解决

scanf("%d",&n); //n表示参与的总数

sum=n;//sum为在场总数

for(i=0;i

for(k=0,i=1;;k++) //每一轮的循环 用k表示第几位选手 i表示报的数

{

printf("\n");

printf("No.%d now is %d",k+1,i);

if(k==n-1 && sum==1) {printf("\n***Winner has been produced***\n"); break;} //结束循环的条件:在场仅为一人 即sum==1 前面加上k==n-1是为了最后一轮也能完整展示

if(a[k]==0 && k==n-1) {k=-1; printf(" \nEnd of the Round \nLeft:%d\n",sum); continue;} //一轮循环结束的标志(最后一个已被淘汰)

if(a[k]==0) {printf(" skip"); sum——; continue;} //被跳过:人被跳过 循环也跳过

if(i%3==0) {a[k]=0; printf(" out");}//报到3的被淘汰

else printf(" valid");

if(k==n-1)

{

k=-1;

printf(" \nEnd of the Round \nLeft:%d\n",sum);//一轮循环结束的标志

}

i=i+1; //每个人报的数字递增

}

for(i=0;i<=n;i++) //找到数组中唯一的1 即获胜者

{

if(a[i]==1)

final_num=i+1;

}

printf("\n");

printf("The winner is No.%d\n",final_num);

}

当总数为7时 程序运算的内容应该如下:

Please enter n(<120):7

No.1 now is 1 valid

No.2 now is 2 valid

No.3 now is 3 out

No.4 now is 4 valid

No.5 now is 5 valid

No.6 now is 6 out

No.7 now is 7 valid

End of the Round

Left:5

No.1 now is 8 valid

No.2 now is 9 out

No.3 now is 10 skip

No.4 now is 10 valid

No.5 now is 11 valid

No.6 now is 12 skip

No.7 now is 12 out

End of the Round

Left:3

No.1 now is 13 valid

No.2 now is 14 skip

No.3 now is 14 skip

No.4 now is 14 valid

No.5 now is 15 out

No.6 now is 16 skip

No.7 now is 16

End of the Round

Left:2

No.1 now is 16 valid

No.2 now is 17 skip

No.3 now is 17 skip

No.4 now is 17 valid

No.5 now is 18 skip

No.6 now is 18 skip

No.7 now is 18

End of the Round

Left:2

No.1 now is 18 out

No.2 now is 19 skip

No.3 now is 19 skip

No.4 now is 19 valid

No.5 now is 20 skip

No.6 now is 20 skip

No.7 now is 20

***Winner has been produced***

The winner is No.4

这种方法只是很简单的一种思路,程序也写的不是很有条理,有很多更好的实现方式,因为这种较为简洁易懂,所以展示在这里。

你可能感兴趣的:(c语言报数问题程序)