前期做了1篇循环数循环数(模拟(C语言))-CSDN博客的题解,虽然看的人不是很多,但觉得能帮到一部分编程初学者和爱好者也非常不错
本次做的这篇文章也是一道模拟题(难易区别不好说,感觉因人而异)
问题描述
n 个人围成一圈, 并依次编号1~n,。从编号为1 的人开始,按顺时针方向每隔一人选出一个,剩下的人重新围成一圈,如此循环直到剩下两人,这剩下的两人就是幸运儿。如果你想成为最后两个幸运儿,请问开始时应该站在什么位置?(设3<=n<=50)
输入
有多个测试序列。每行是开始时的人数n
输出
第1 行是选出顺序,位置编号之间用一个空格分开,包括末尾空格。
第2 行是两名幸运儿的开始位置(按升序排列)。
样例输入
12 20 45
样例输出
2 4 6 8 10 12 3 7 11 5 1 9 2 4 6 8 10 12 14 16 18 20 3 7 11 15 19 5 13 9 1 17 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 3 7 11 15 19 23 27 31 35 39 43 5 13 21 29 37 45 9 25 41 17 1 33
问题分析
主要要思考的就是人是否已经被选出,判断何时把人选出,怎样一圈结束一圈又起,什么时候结束,如何用程序语言来模拟这个过程
问题解决
1.人是否还在圈里
理所当然的可以想到用数组来模拟这个过程
int a[65];
for(i=1; i<=n; i++) {
a[i]=0;
}
要注意初始化,数组开大一点没关系
后期便可用数组a[]的值来模拟人是否还在圈里
这里推荐洛谷上的一道题,或许可以加深映像
P1047 [NOIP2005 普及组] 校门外的树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
2.何时把人选出
根据题目要求,按顺时针方向每隔一人选出一个,即可用一个变量来存储隔了几个人了
int flag=0;
for(i=1; i<=n; i++) {
if(a[i]==0)
flag++;
if(flag==2) {
a[i]=1;
flag=0;
index_n--;
printf("%d ",i);
}
}
以flag的值进行判断并做出相应处理
3.结束标志
如此循环直到剩下两人,这剩下的两人就是幸运儿。
由此可定义一个变量保存相应人数,这里用的是
index_n=n;
再用上while循环即可
while(index_n>2) {
...
for(i=1; i<=n; i++) {
...
}//一圈结束,又重新开始
}
用这个也正好模拟了剩下的人重新围成一圈,然后又重新选人,最终达到题目要求
4.最后输出
每一圈选人,想想可知道1是必然不会被选出的
从后面开始找
找到a[i]==0的输出就行了
完整代码
#include<stdio.h>
int main() {
int n;
while(scanf("%d",&n)!=EOF) {
int i;
int a[65];
for(i=1; i<=n; i++) { //初始化
a[i]=0;
}
int index_n=n;
while(index_n>2) {
int flag=0;
for(i=1; i<=n; i++) { //模拟选人
if(a[i]==0)
flag++;
if(flag==2) {
a[i]=1;
flag=0;
index_n--; //还剩多少人
printf("%d ",i);
}
}
}
printf("\n");
printf("1 "); //1是必须的
for(i=2;i<=n;i++){
if(a[i]==0)
printf("%d\n",i);
}
}
return 0;
}
留给读者的话
做模拟题主要是要读懂题意,然后把问题的步骤分析清楚,自然就能迎刃而解了
标签:12,int,一圈,C语言,选出,幸运儿,模拟 From: https://blog.csdn.net/2301_79695613/article/details/136947327