有 num 个人围坐在圆桌周围,现在从第 n 个人开始报数,数到第 interval 的人出列,然后从出列的下一个人重新开始报数,数到第 interval 的人又出列,如此重复直到所有的人全部出列为止
当输入 interval 后,求最后胜出的人(打印其下标)
#include <iostream>
using namespace std;
int main()
{
int num;
cout<<"Josephus圈共多少人:";
cin >> num;
int a[num];
for (int i = 0; i < num; i++)
{
a[i] = i + 1;
}
cout << "几个人算一轮:";
int interval;
cin >> interval;
for (int i = 0; i < num; i++)
{
cout << a[i] << ",";
}
cout << endl;
int i;
cout<<"从第几个人开始数:";
cin >> i;
i = i-2; 为了确保从第 n 个人开始报数
for(int k = 1; k < num; k++) 轮数,num-1 轮(为了剩下一个人)
{
for(int j = 0; j < interval;) 每数 interval 个数淘汰一个人
{
i = (i+1) % num; 取模是为了保证淘汰人的下标永远在 num 的范围内
if(a[i]!=0) 跳过淘汰的人
{
j++;
}
}
cout<<a[i]<<"被淘汰掉了"<<endl;
a[i] = 0;
}
for (int i = 0; i < num; i++) 打印不为 0 的元素即最后胜出的人
{
if(a[i] != 0)
{
cout<<a[i]<<"是winner!";
}
}
return 0;
}
Input
Josephus圈共多少人:10
几个人算一轮:3
1,2,3,4,5,6,7,8,9,10,
从第几个人开始数:1
Output
3被淘汰掉了
6被淘汰掉了
9被淘汰掉了
2被淘汰掉了
7被淘汰掉了
1被淘汰掉了
8被淘汰掉了
5被淘汰掉了
10被淘汰掉了
4是winner!
用到了取模的方法
核心思想就是:将淘汰的人标记为 0 ,一直循环、标记,直到只剩一个人为止