C语言||约瑟夫问题(丢手绢问题)

20518
用时:1h
编程数组或指针实现约瑟夫环问题。 题目为:编号为1,2… n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个开始重新从1报数,如此下去,直至所有人全部出列为止,设计一个程序求出出列顺序。
示例 输入数据序列:1,2,3,4,5,6,7,8,9,10
m=4,从1开始
输出数据序列:4,8,2,7,3,10,9,1,6,5
分析

01.阅读题目读取重点是:每四个杀一个(逢4杀1,后补齐)
02.往未知长度的数组里输入一些数据,并判断输入个数?
答:由基本知识可知,C中不能直接这个int arr[];这个可以出现在我们自己定义的函数中,但是不能出现在main函数中,是部合法的。所以这种情况一般可以用动态数组,或者是用一个较大的数来临时当数组长度,但是这又会出现一个问题:怎么让输入这一个过程结束?因为我们用一个较大的临时长度,所以就应该用考虑用回车来终结这个循环?关于回车结束循环请看这里 👧点击这里↖
03.逢m杀1到底是怎么实现?
答:首先是一个循环,循环判断条件是有多少数就循环多少次(最蠢但是最有用的方法),然后是循环里的条件:
①if(* (p+i)!=0) k++ //k就是从1开始报数的开始
②if(k==M) /逢M杀1,//那么k到了4就要杀数了详细见下面/
③if(i= =n) i=0;//遍历到最后了就再回到起点!
实操:

#include <stdio.h>
#define nmax 50
#define M 4		                         //逢M去1	
int main(void)
{

  int i=0,k,m,n=0,num[nmax],*p;
  char s;								//字符型变量s用来判断是否结束下面的循环
	while(i<nmax&&s!='\n')				
	{
		scanf("%d",&num[i]);			//输入要求输入的从1开始的有顺序的数
		s=getchar(); 
		n++;							//记录数组长度
		i++;					
	}
  p=num;								//p指向num数组
  i=0;								
  k=0;
  m=0;									//将i,k,m初始化
  while(m<n-1)							
  {
    if(*(p+i)!=0)
      k++;								
    if(k==M)							
    {
		printf("%d ",*(p+i));
        *(p+i)=0;						//将此处的值先输出后做好标记(为0)下次循环判断时就可跳过此数
	    k=0;
	    m++;
    }
    i++;
    if(i==n)
        i=0;							    //变量i表示数组偏移,到了数组结束就重置到数组首地址
  }
  	while(*p==0)
  	    p++;
  	printf("%d",*p);					//因为最后肯定会剩余一个数所以最后一个数不满足上面的if条件,直接最后输出
  	
 return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值