现在的位置: 首页 > 综合 > 正文

Joseph环-指针数组法

2018年11月05日 ⁄ 综合 ⁄ 共 1201字 ⁄ 字号 评论关闭

问题描述: n个人(id:1~n)围成一圈 从第一人开始计数 每数到3 那个人离去 ,然后从下一个人开始 重新从1开始计数,请问最后一个人离开是的谁? 答案用id表示

 

解决思路:

        用指针数组存储ID数组每个元素的地址,每次循环减少指针数组元素的个数,但是ID数组元素内容变化,地址不变(关键步骤),最后剩下的指针数组元素指向剩下人物的ID,该方法比循环链表速度快 复杂度相当

 
为解释我的想法 我举个实例:
假设有6个人玩约瑟夫环游戏:1,2,3,4,5,6                           L为初始围圈人数(L=6)


第一次循环有6个人:  1,2,3,4,5,6
id为4,6的人离开圈子,剩下的id为: 1,2,4,5

我在这里做个映射,预测1,2,4,5在下一次循环的id


L=6
第一个人 ID:1->7(第一个人在第二圈的id)7=1+L(6为当前圈子人数,因为数到1,还没有离开圈子,所以下一次到第一个人的时候,必然为1+L) 

L=6

第二个人  ID: 2-> 8 (第二个人在第二圈的id)8=2+L(6为当前圈子人数,因为数到2,还没有离开圈子,所以下一次到第一个人的时候,必然为2+L) 

 

第三个人离开了

L=5

第四个个人  ID: 4-> 9 (第四个人在第二圈的id)9=4+L(5为当前圈子人数,因为数到3时,有一个人离开圈子,X下一个人要填补它的位置,所以下一次到第一个人的时候,必然为4+L)

 

L=5 

第五个人  id: 5-> 10(第五个人在第二圈的id)10=5+L(5为当前圈子人数,因为数到3时,有一个人离开圈子,所以下一次到第一个人的时候,必然为5+L)  

 

 

 第二圈循环时有四个人: 7,8,9,10
        id为9的人离开圈子,剩下的为7,8,10  
      再预测7,8,10在第三圈的ID
      以此类推 最后剩下一个人

 

指针数组法
#include <stdio.h>
#include <stdlib.h>
void choose(int *c[],int j)
{
  int h,i,k;
  int **q;
  q=c;
  h=j;
  while(h>1){     //h为当前圈内人数
             k=0;    
             for(i=0;i<j;i++)    //每次循环的圈内人数
               {
                   
                    if(**q%3==0) {h--;}
                    else {
                         c[k]=c[i];
                         *c[k]=*c[k]+h;  //更新留在圈内的人在下一次循环的ID
                         k++;
                        }
                q++;
               }
              j=h;
              q=c;
             }    
}
 
int main(int argc, char *argv[])
{
   int k,i; 
   printf("请输入围圈人数\n");
   scanf("%d",&k);
   
    int a[k][1],*b[k];
   for(i=0;i<k;i++)
   {
    a[i][0]=i+1;
    b[i]=a[i];
   }
   int *p;  
   p=a[0];
   choose(b,k);
   printf("%d\n",b[0]-p+1); 
  system("PAUSE"); 
  return 0;
}

抱歉!评论已关闭.