题目背景
约瑟夫是一个无聊的人!!!
题目描述
n个人(n<=100)围成一圈,从第一个人开始报数,数到m的人出列,再由下一个人重新从1开始报数,数到m的人再出圈,……依次类推,直到所有的人都出圈,请输出依次出圈人的编号.
输入输出格式
输入格式:n m
输出格式:出圈的编号
输入输出样例
说明
m, n \le 100
m,n≤100
解法一:
模拟
#include <stdio.h>
#include<iostream>
using namespace std;
int vis[101];
int main()
{
int n, m;
cin >> n >> m;
int k = 0;
for (int num = 0; num < n; num++)
{
for (int i = 0; i < m; i++)
{
if (++k>n)k = 1;
if (vis[k]) i--;
}
printf("%d ",k);
vis[k] = 1;
}
return 0;
}
解法二:数学推导
参考题解:http://blog.csdn.net/ordinarycrazy/article/details/77073455
#include <stdio.h>
#include<iostream>
using namespace std;
int f[101][101];
int josef(int n, int m, int i)
{
if (f[n][i]) return f[n][i];
if (i == 1) return (m - 1) % n;
return f[n][i]=(josef(n - 1, m, i - 1) + m) % n;
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
printf("%d ", josef(n, m, i) + 1);
return 0;
}