约瑟夫环(简单版)c语言解决

传说约瑟夫当年活下来就是靠快速计算这个问题。

 

n 个人围成一圈,编号依次为 1,2,3…n。从第一个人开始报数,数到 m 的人出列,再由下一个人重新从 1 开始报数,数到 m 的人再出圈。以此类推,直到所有的人都出列。请输出依次出圈人的编号。

输入格式

两个整数 n,m, 1<=n,m<=100

输出格式

n 个用空格分隔的整数,表示出圈人的编号。

#include<stdio.h>
int main()
{// 约瑟夫环的简单问题 
	int n,m,d=0,k=0,i,a[100]={0};//随便定义了一个100个内存的数组值为0 
	scanf("%d%d",&n,&m);//n为人数,m为报号数,k为实际计数,i为原座位顺序数 
	for(i=1;k!=n;i++)//d为暂时计数(0到m间循环) 
	{
		if(i>n)//这个步骤可以实现数组像圆圈一样多次重复的循环 
		{
			i=1;//i代表每个人原先的顺序位置 
		}
		if(a[i]==0)//数组的定义0和1可以实现标记未出局和出局的具体人 
		{
			d++;//如果进入循环,暂时计数便+1; 
			if(d==m)//当暂时计数达到出局的位置,令数组值为1,出局 
			{
				d=0;//使暂时计数程序循环 
				a[i]=1;
				printf("%d",i);//输出出局的具体座位数 
				if(k!=n)//此处为格式需求,只要不是最后一行,其间输出空格 
				{
					printf(" "); 
				}
				k++;//此处的K递增为出局的人数,该for循环语句的终止条件为出局数=n 
				
			}
		}
	}
}

题目二:

约瑟夫

要点.‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬模拟法,做好问题向符号的映射,然后按照题目描述的过程,在符号上进行操作。‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬


描述

设 n(n>0)个人围成一个环,个人的编号分别为1,2,…,n,从第 1 个人开始报数,报到 时停止报数,报 的人出环,再从他的下一个人起重新报数,报到 时停止报数,报m的人出环,……,如此下去,直到所有人全部出环为止。对于任意给定 和 m,求 个人出环的次序。‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬

输入

空格分隔的两个小于10000的非负整数,第一个表示人数,第二个表示需要报的数目。‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬

输出

最后一个出环人的编号‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬

示例

输入
5 3

输出
4
#include <iostream>
using namespace std;
int main()
{
	int arr[99999],k=0,c=0,n,m;
	cin>>n>>m;//输入n个人和报数到m出局; 
	for(int i=1;i<=n;i++)
	{
		arr[i]=1;
	}//用arr数组标记每个人,如果arr[i]为1,表示未出局,若某个人数到m,令他出局,则将他标记为0,出局。 
	for(int i=1;;i++)
	{
	//cout<<i<<endl;
		if(arr[i]==1)//如果未出局,则继续数数 
		{
			
			k++;//报数+1 
			if(k==m)//如果k数数报到m,令这个人出局,标记为0,c表示出局的人数 
			{
			arr[i]=0;
			c++;
				k=0;//报数到m后重新归0,重新从0开始数 
			}
		}
		if(c==n)//如果c出局人数到n,则可以停止了,所有人都出局了,游戏结束 
		{
		cout<<i<<endl;//当前i为最后一个出局人的位置 
			break;
			
		}
		if(i==n) i=0;//每个人座位顺序遍历完后从0开始 
  	
	}
	
}
#include <iostream>
using namespace std;
int main()
{
    int r[10000]={0}, n, m;
    int counter, i = -1, num = 0;
    cin>>n>>m;
    while(num<n-1){//num是出局人数
        counter=0;
        while(counter<m){
            i=(i+1)%n;//counter实现报数遍历循环,i是每个人的座位号
            if(r[i]!=1) counter++;
        }
        r[i]=1; num++;
    }
    for (i = 0; i < n; i++)
        if (r[i] == 0)   //返回编号
            cout << i+1;
    return 0;
}

这个代码建议读者多敲几遍,边理解边敲。

请关注我,真诚地感谢读者的支持,

  • 10
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值