洛谷P1996 约瑟夫问题

本文详细解析了约瑟夫环问题,通过使用标志数组存储游戏过程中每个人的状态,模拟报数游戏过程,直至所有人出圈。适用于理解递归与循环算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目背景                                         

约瑟夫是一个无聊的人!!!     

题目描述 

n个人(n<=100)围成一圈,从第一个人开始报数,数到m的人出列,再由下一个人重新从1开始报数,数到m的人再出圈,……依次类推,直到所有的人都出圈,请输出依次出圈人的编号.

输入格式

n m

输出格式

出圈的编号

输入输出样例

输入#1     

10 3

输出 #1 

3 6 9 2 7 1 8 5 10 4

说明/提示 

 m,n≤100

解题思路: 

1 、由于对于每个人只有出圈和没有出圈两种状态,因此可以用真假标志数组存储游戏过程中每个人的状态。

2 、开始的时候,给标志数组赋初值假,则全部在圈内。

3 、模拟报数游戏的过程,直到所有的人出圈为止。

#include <bits/stdc++.h>
using namespace std;
int n,m;
int a[105];
int main(){//a[t]如果为真就表示出圈,为假就表示还在圈内 
   cin >> n >> m;
   int t=0,s=0,f=0;//t从头遍历每个数,初始为0;s递增到m就置0
   while(f!=n){//f表示出圈的人数,递增到n就结束 
	  t++;
	  if(t==n+1)//t遍历到了最后+1,此时将其置成1; 
		 t=1;
	  if(a[t]==0)//如果a[t]为假,就让s+1 
		 s++;
	  if(s==m){//s等于m,此时t表示的人应该出圈,然后让s变为0 
		 s=0;
		 a[t]=1;//出圈,让其变为真 
		 cout << t << ' ';//打印,输出 
		 f++;//出圈人数加1 
	  }
   }
   return 0;
}

程序运行结果 :

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值