出圈问题整理

设有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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值