约瑟夫环
一、题目内容
题目描述
n 个人的编号是 1~n,如果他们依编号按顺时针排成一个圆圈,从编号是1的人开始顺时针报数。
(报数是从1报起)当报到 k 的时候,这个人就退出游戏圈。下一个人重新从1开始报数。求最后剩下的人的编号。这就是著名的约瑟夫环问题。
本题目就是已知 n,k 的情况下,求最后剩下的人的编号。
输入
题目的输入是一行,2个空格分开的整数n, k
约定:0 < n,k < 1百万
输出
要求输出一个整数,表示最后剩下的人的编号。
样例输入
10 3
样例输出
4
二、思路分析
方法一:动态数组
方法二:递归
方法三:递推公式
三、代码实现
#include <bits/stdc++.h>
using namespace std;
int n, k, x;
int main() {
cin >> n >> k;
vector<int> num(n); //定义动态数组
for (int i = 0; i < n; i++)
num[i] = i + 1; //初始化赋值
while (1) {
x = (x + k - 1) % num.size(); //取%表示构成环
num.erase(num.begin() + x); //删除已经选中的
if (num.size() == 1) { //只剩一个
cout << num[0] << endl;
break;
}
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int f(int n, int m) {
if (n == 1)
return 1;
else
return (f(n - 1, m) + m - 1) % n + 1;
}
int main() {
int n, m;
scanf("%d %d", &n, &m);
printf("%d\n", f(n, m));
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m, s, i;
cin >> n >> m;
for (i = 2; i <= n; i++) {
s = (s + m) % i;
}
cout << s + 1 << endl;
return 0;
}
加油哦! 如有错误和需要改进完善之处,欢迎大家纠正指教。