约瑟夫环问题
- 问题描述
- 数据结构设置
- 过程代码
问题描述
n个小朋友做成一圈,编号分别是分别为1-n,2号小朋友坐在1号小朋友顺时针方向,3号小朋友坐在2号小朋友顺时针方向……1号小朋友坐在n号小朋友顺时针方向;对于给定输入n、k,从第一位小朋友开始报数,第一位小朋友报数为1,下面的小朋友每次报数增加1,当某一位小朋友报数报到k的整数倍或者报的数的个位数为k时,该小朋友被淘汰出局。最终剩下一位小朋友,该小朋友为获胜者。
输入:n、k
输出:获胜的小朋友的编号
利用数据结构来简化问题
分析问题,需要存储的是小朋友的编号、小朋友的状态(是否淘汰出局)、小朋友的报数,环状结构则通过进行mod n实现。
因此选择结构体数组来进行数据的存储。
结构体设置
struct Item{
int id;
int num;
bool state;
Item(int _id,int _num,bool _state=true){
id = _id;
num = _num;
state = _state;
}
};
过程代码
经过数据结构的恰当选择,过程已经变得极为简单,只需要找出前一个报数者和后一个报数者的数组下标即可。当两个下标相等时,游戏结束。下面是完整代码:
#include <iostream>
#include <vector>
using namespace std;
struct Item{
int id;
int num;
bool state;
Item(int _id,int _num,bool _state=true){
id = _id;
num = _num;
state = _state;
}
};
int main(){
int n,k;
cin >> n >> k;
vector<Item> loop;
for(int i=0;i<n;i++)
loop.push_back(Item(i+1,0));
int pre=0,next;
loop[0].num = 1;
while(1){
next = (pre+1)%n;
while(loop[next].state!=true)
next = (next+1)%n;
if(next==pre){
cout << loop[next].id;
return 0;
}
else{
loop[next].num = loop[pre].num+1;
if(loop[next].num%k==0 || loop[next].num%10==k)
loop[next].state=false;
pre = next;
}
}
}