设有N个人围坐一圈并按顺时针方向从1到n编号,从第s个人开始进行1到m的报数,报数到第个m人,此人出圈,再从他的下一个人重新开始1到m的报数,如此进行下去直到所有的人都出圈为止。要求按出圈次序,每10人一组,给出这n个人的顺序表。*/
方法一:普通排列,先将这m个人放到一个数组中,按序号编号座位号,从1开始报数,第m个人出圈(将该位置设置为0作为出圈标准),如果到最后一个人,则从头开始计数;
实现方法如下:供大家参考
假设有25个人,m值为3
int iNext=0;
int iNum =0;
int People[50];
int iGet = 0;//出来的人数
int iTotal =25;//总人数
int *p = People;
for (int i = 0;i<25;i++)
{
*(p+i) = i+1;
}
while (iGet < iTotal-1)
{
//如果这个位置上有人,则inum++
if (*(p+iNext) != 0) {
iNum++;
}
//如果是规定的数,这个人出圈,即该位设置为0
if (3 == iNum) {
*(p+iNext) = 0;//将该位置设置为0
iNum = 0;//重新开始计算
iGet ++;//让出圈人数加1
}
iNext++;//指向下一个人员
if (iNext == 25) {
iNext = 0;//如果到最后一个成员,则从头开始计数
}
}
while (*p==0)
{
p++;
}
cout<<"该位置为"<<*p<<endl;
方法二、双向链表实现
struct Queue
{
int num;
Queue *next;
};
void CreateQue(Queue *pHead,int iTotal)
{
//创建头指针,将头指针指向自己
pHead->num = 1;
pHead->next = pHead;
Queue *pQue = pHead;//标识为指针,作为一个临时游标
//创建节点
for (int i=2;i<=iTotal;i++)
{
Queue *pTemp = new Queue;
pTemp->num = i;
//将该节点的下一指向指向头指针
pTemp->next = pHead;
//将标识指针指向该节点,即上一个指针的next指向
pQue->next = pTemp;
//将标识指针指向该节点
pQue = pTemp;
}
}
void GetQue(Queue *pHead,int iGet)
{
Queue *p1=pHead,*p2 = pHead;//设置两个指针标识位
int inum = 1;//序号
while (pHead->next != pHead)
{
p1 = p2;
p2 = p1->next;
inum +=1;
if (inum%iGet == 0) {
printf("当前第%d个人出圈!/n",p2->num);
p1->next = p2->next;
delete p2;
p2 =p1;//设置两个指针标准同一个节点
//将头指针指向删除节点的上一个节点
pHead = p1;
}
}
printf("最后胜出的是%d/n",p1->num);
}
int main(int argc,char** argv)
{
int total =45,iGet = 3;
//声明一个头指针
Queue *pHead = new Queue;
//创建一个循环队列
CreateQue(pHead,total);
//出圈排序
GetQue(pHead,iGet);
return 0;
}