说明
约瑟夫问题来源于公元1世纪的犹太历史学家Josephus。
问题描述,有n个人(分别以编号1,2,3...n表示)围成一个圆圈,从编号为1的人开始进行1~m正向报数,报到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;如此重复下去,直到所有的人全部出列,求最后一个出列人的编号。
输入格式
输入文件仅有一行包含二个用空格隔开的整数(N,M, 2≤N,M≤1000)。
输出格式
输出文件仅有一行包含一个整数表示一个整数,表示最后一个人在队列中的编号。
样例
输入数据
8 3
输出样例
7
做题步骤
变量设置
用k表示人,s表示报的数,t表示走了多少人,n表示有几个人,m表示报到几出局,一个数组a储存
以下代码↓
int n,i,m,t,s,k;
int a[110];
赋值
(a[i]==0表示出局,a[i]==1表示在内)
for(i=1;i<=n;i++) a[i]=1;
s=t=k=0;
分析
求最后一个出局的,那用while更方便
while(t>n){
}
1~n个人围成一圈,也就是只要(人数%n==0)或(人数>=n)的话,人数就等于1。
k++;
if(k>n) k=1;
如果这个人在游戏中,那么就要报数
if(a[k]==1) s++;
然后如果报到了m,那么就出局,s重新计数,a[k]就=0;
if(s==m){
t++;
a[k]=0;
s=0;
}
代码编写
#include <bits/stdc++.h>
using namespace std;
int n,i,m,t,s,k;
int a[110];
int main(){
cin>>n>>m;
for(i=1;i<=n;i++) a[i]=1;
s=t=k=0;
while (t<n){
k++;
if(k>n) k=1;
if(a[k]) s++;
if(s==m){
t++;
a[k]=0;
s=0;
}
}cout<<k;
return 0;
}