约瑟夫问题(C++编写)

题目描述:
设有n个人围坐一圈并按顺时针方向从1到n编号,从第1个人开始进行1到m的报数,
报数到第个m人,此人出圈,再从他的下一个人重新开始1到m的报数,如此进行下去直到所剩下一人为止。

输入多行,每行2个数,分别表示n和m.

输出每一行中最后剩下这个人的编号.

样例输入
10 3
样例输出
4

解题思路:
首先大家要搞明白这道题在草稿纸上的运算过程,假设有 n = 10个人坐在一起,按顺序从1-10开始编号,m = 3,刚开始我们先引入一个变量 num=0。
第一步,访问到编号为1的这个人,此时 num = 0 + 1 = 1,num != 3,
第二步,访问编号为2的这个人,此时 num = 1 + 1 = 2, num != 3,
第三步,访问编号为3的这个人,注意!此时 num = 2 + 1 = 3,发现 num == 3,那么我们就需要把编号为3的这个人剔除,这里为了方便,我们可以让他的编号变成 0 ,同时,我们需要让 num 这个变量从3 变成 0 ,可能很多小伙伴不知道这是什么意思,大家想一下,我们在草稿纸上画的时候遇到num = 3 时是不是就说明这个数已经被找到了一个,那么num 是不是就要开始重新计数,因为这样才可以找出其他报 3 也就是( m )的人。
接下来重复着几个步骤,发现在第一轮中,大家一共比较了 n 次,把编号为 3 ,6,9 数字给剔除出去了(也就是让他们变为了 0 )
在第一回合中,大家比较了 n 次,第二回合中,由于第一回合大家剔除了 3 个数字,所以第二回合就只需要比较 ( n - 3 )个数字就可以了。这里我们就需要一个while循环,作用是当数组里面只有 1 个数字时,那么就停止比较,输出结果。

以下是代码:

#include<iostream>
using namespace std;
void Compare(int n1,int n2)
{
    while(n1!=0&&n2!=1) 		//n2是不能等于1的
    {
        int a[n1],b=n1,c=0;
        for(int i=0;i<n1;i++)
            a[i] = i+1; 				//给a[i]赋值
        while(b>1) 					    //b代表了需要比较数字的个数,当等于1时就跳出循环
        {
            for(int i=0;i<n1;i++)
            {
               //当a[i]不等于0时,那么计数器就加1
               
                if(a[i]!=0)					
                    c++;
                    
               //当c==n2时,就把a[i]变为0,同时计数器恢复为0,那么需要比较的数字也就减1
               
                if(c==n2) 					
                {
                    a[i] = 0;
                    c=0;
                    --b;
                }
                /*
                	这里大家一定要注意两个if的书写顺序,因为一上来大家是先把数组中的数字和0比较,
                如果是0,那么就跳过,如果不是0,那么 c 就 +1,然后再把 c 和 n2 进行比较。并不是一上来就
                把 c 和 n2 比的,我之前以为反正两个 if 都是做判断的顺序无所谓,但事实证明我这个想法错的很离谱!
                */
            }

        }
        for(int i=0;i<n1;i++)
            if(a[i]!=0)
                cout<<a[i]<<endl;
        cin>>n1>>n2;
    }
}
int main()
{
    int num1,num2;
    cin>>num1>>num2;
    Compare(num1,num2);
    return 0;
}

如果有什么地方是大家觉得不足的,欢迎大家前来指出!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值