约瑟夫环-循环队列算法(曾微软,google笔试题)
这也是我们聚会时常常做的游戏之一。
算法思路:
此处我使用循环链表模拟人围城一圈,每一个结点代表一个人。链表是一个有序链表,链表结点数据域是一个整型,代表人的序号。出局等同于链表删除元素,每次出局后重新从1k开始数。知道剩下最后一个。最后一个的判定是:while((p->num)!=(p->next->num))。循环跳出,就是到最后一个人。
算法代码如下:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define NUM 5 //游戏人数 4 #define OUT 3 // 逢3出局 5 struct Person 6 { 7 int num; 8 struct Person *next; 9 }; 10 int main() 11 { int i,j; 12 int cnt=1; 13 int index=0; 14 int c[NUM]={0}; 15 struct Person person[NUM],*p; 16 printf("\n游戏人数是 %d 人\n逢 %d 出局\n\n",NUM,OUT); 17 for(i=0;i<NUM;i++) 18 { 19 person[i].num=i+1; 20 person[i].next=&person[(i+1)%NUM]; 21 } 22 p=&person[0]; 23 while((p->num)!=(p->next->num)) 24 { 25 while(cnt<OUT-1) 26 { 27 p=p->next; 28 cnt++; 29 } 30 c[index]=p->next->num; 31 index++; 32 p->next=p->next->next; 33 p=p->next; 34 cnt=1; 35 } 36 c[index]=p->num; 37 printf("最后一个人是:%d\n\n",p->num); 38 printf("出局的顺序是:\n"); 39 for(j=0;j<NUM;j++) 40 { 41 printf("-->%d",c[j]); 42 } 43 printf("\n\n"); 44 system("pause"); 45 return 0; 46 }
实验截图:
手与大脑的距离决定了理想与现实的相似度