问题是这样的:n个人参加游戏,从1开始报数,报到3的退出游戏,最后胜利的是几号?
解法一:循环数组
#include<iostream>
#include<cassert>
using namespace std;
#define DENGER_NUM 3
int joseph(int n)
{
assert(n>0);
int *arr=(int*)malloc(sizeof(int)*n);
int i=0;//数组的下标
int count=n;//参与游戏的人数
int tmp=0;
//1表示还在,0表示已经出局
for(i=0;i<n;i++)
{
arr[i]=1;
}
i=0;
while(count>1)//count一定要大于1,不能大于0
{
if(arr[i]==1)
{
tmp++;
if(tmp==DENGER_NUM)
{
arr[i]=0;
tmp=0;
count--;
}
}
i++;
i=(i+n)%n;
}
for(i=0;i<n;i++)
{
if(arr[i]==1)
break;
}
return i+1;
}
int main()
{
cout<<joseph(1)<<endl;
cout<<joseph(2)<<endl;
cout<<joseph(3)<<endl;
cout<<joseph(4)<<endl;
return 0;
}
形成循环数组,边界的做法可如下:
i=(i+n)%n;
或者 if(n==n) i=0;
或者 i=(i==n-1) ?0 : i+1;
解法二:循环链表
#include<iostream>
#include<cassert>
using namespace std;
#define DENGER_NUM 3
typedef struct Node
{
int data;
Node* next;
}Node;
Node* BuyNode()
{
Node* s=(Node*)malloc(sizeof(Node));
if(NULL==s)
exit(1);
memset(s,sizeof(Node),0);
return s;
}
Node* Create(int n)
{
assert(n>0);
Node* head=BuyNode();
Node* p=head;
Node* s=NULL;
int i=1;
while(i<=n)
{
s=BuyNode();
s->data=i++;
//s->next=p->next;
p->next=s;
p=s;
}
p->next=head->next;//构成循环链表
free(head);
head=NULL;
return p->next;//返回循环链表的头
}
int main()
{
int n;
while(1)
{
cout<<"Please Input People_num:";
cin>>n;
Node* p=Create(n);//创建一个循环链表,p指向头
Node* tmp=NULL;//出局
while(p!=p->next)
{
for(int i=1;i<DENGER_NUM-1;i++)//DENGER_NUM-1主要是为了让p指向删除的前驱
{
p=p->next;
}
tmp=p->next;
p->next=tmp->next;
free(tmp);
tmp=NULL;
p=p->next;
}
cout<<"最后胜利的是"<<p->data<<endl;
}
return 0;
}