此代码解决是Josephus问题的变种,即n个数中,第m个数出列组成新数组,直到数组中只剩一个数,则此数为结果。
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
//josephus
/*
解题思路:
_len长度的元素值从1~_len的数组,每(_space+1)个数组成一组,丢弃前_space个数并留下第_space+1个数。
若_len长度非(_space+1)整数倍,则剩余的元素保存于数组首(不会覆盖掉第一个待保存的数),其余元素依次处理
,保留下的数紧挨着存放,最终组成一个更小的数组(原数组的约1/3)。
一直处理数组直到数组的有效长度len小于等于_space,此时整个数组无法再通过之前的方法获取待保留的数,
因此进行特殊处理。最终获取结果。
*/
void josephus(int *_arr, int _len, int _space){
//特殊情况
if(_space<1){
cout<<"问题无解!"<<endl;
return;
}
else if(_space>_len){
cout<<"结果:"<<_arr[_space%_len]<<endl;
return;
}
int space=0; //间隔计数
int len=_len; //数组有效长度
//数组有效长度大于_space,则可直接通过循环数组获取待保留的数
while(len>_space){
int index=0; //标示待保留的数保存的位置
int left=len%(_space+1); //不能组成(_space+1)对的剩余数个数
if(left!=0){
for(int i=0;i<left;i++){
_arr[i]=_arr[len-left+i];
}
index+=left;
space+=left;
}
for(int i=left;i!=len;i++){
if(space!=_space)
space++;
else{
_arr[index++]=_arr[i];
space=0;
}
}
len=index; //index标示有效数组长度
}
//剩余有效数组不能组合成一个(_space+1)对,因此特殊处理
if(len==1) cout<<"结果:"<<_arr[0]<<endl;
else {
int index=0;
space=0;
while(space!=_space){
space++;
index++;
if(index==len) index=0;
}
cout<<"结果:"<<_arr[index]<<endl;
}
}
//main
int main(){
int len=0;
int space=0;
cout << "==========Josephus==========" << endl;
cout<<"数字个数:";
cin>>len;
cout<<"循环间隔:";
cin>>space;
int* _arr=new int[len];
for(int i=0;i<len;i++)
_arr[i]=i+1;
josephus(_arr,len,space);
cout<<endl;
return 0;
}