问题描述:
n个人围成一圈,从第k个人开始报数(0<k<n)报到m(m>0)的人出列,出列的人的下一个人继续报数,每到m的人就出列,求最后出列的人的编号。
Input:n= 3 k = 1 m= 3
Output: 2
实现方法:
有两种实现方法,可以采用数组也可以采用链表
方法一: 用数组存放数据
在类ArraySort的头文件中定义以下两个方法
void YueseFuArr(int arr1[],int result[],int len,int m,int k);
void TestOfYueseFuArr();
然后在cpp文件中实现如下方法:
void ArraySort::YueseFuArr(int arr1[],int result[],int len, int m,int k)
{
int i=-1,n=0;
for (int i0=0;i0<k-1;i0++)
{
i++;
}
while(len--){
for (int j=0;j<m;)
{
i=(i+1)%m;
if (arr1[i]!=0)
{
j++;
}
}
result[n++] = arr1[i];
arr1[i] = 0;
}
cout<<"结果:"<<endl;
for (int i=0;i<n;i++)
{
cout<<result[i]<<" ";
}
cout<<endl;
}
void ArraySort::TestOfYueseFuArr(){
int m,n,k;
cout<<"n=";
cin>>n;
cout<<"k=";
cin>>k;
cout<<"m=";
cin>>m;
int *arr1 = new int[n];
int *result = new int[n];
cout<<"原始数组:"<<endl;
for (int i=0;i<10;i++)
{
arr1[i] = i+1;
cout<<arr1[i]<<" ";
}
cout<<endl;
YueseFuArr(arr1,result,n,m,k);
}
在主函数中调用TestOfYueseFuArr方法即可。
运行结果如下:
n=10
k=2
m=10
原始数组:
1 2 3 4 5 6 7 8 9 10
结果:
1 2 4 7 3 10 6 8 5 9
方法二:用链表存储数据
首先定义数据结构:
typedef struct Node
{
int num;
struct Node *next;
}LinkList;
在ListOperator类的头文件中定义如下方法:
LinkList *creatCircle(int n);//创造环装链表
void fun(LinkList *L,int k,int m);逐个输出出列的编号
int TestOfYueSeFuHuan();//测试用例
//约瑟夫环相关操作
LinkList* ListOperator::creatCircle(int n){
LinkList *p,*q,*head;
int i=1;
//p=(LinkList *)malloc(sizeof(LinkList));
p = new LinkList();
p->num=i;
head=p;
for(i=2;i<=n;i++)
{
// q=(LinkList *)malloc(sizeof(LinkList));
q = new LinkList();
q->num=i;
p->next=q;
p=q;
}
p->next=head; /*使链表尾指向链表头 形成循环链表*/
return head;
}
void ListOperator::fun(LinkList *L,int k,int m)
{
int i;
LinkList *p,*s,*q;
p=L;
cout<<"出列顺序为:"<<endl;
for(i=1;i<k;i++)
{
q=p;
p=p->next;
}
while(p->next!=p)
{
for(int j=1; j<m;j++){
q=p;
p=p->next;
}
cout<<p->num<<" ";
s=p;
q->next=p->next;
p=p->next;
free(s);
}
cout<<p->num<<endl;
}
int ListOperator::TestOfYueSeFuHuan(){
LinkList *L;
int n, m,k;
cout<<"n = ";
cin>>n;
cout<<"m = ";
cin>>m;
cout<<"k = ";
cin>>k;
L=creatCircle(n);
fun(L,k,m);
return 0;
}
n = 10
m = 10
k = 1
出列顺序为:
10 1 3 6 2 9 5 7 4 8