C语言实例解析精粹学习笔记——35(报数游戏)
实例35:
设由n个人站成一圈,分别被编号1,2,3,4,……,n。第一个人从1开始报数,每报数位m的人被从圈中推测,其后的人再次从1开始报数,重复上述过程,直至所有人都从圈中退出。
实例解析:
用链表求解本问题,先由n形成一个有n个表元组成的环,其中n个表元依此置值1~n。然后从环的第一个表元出发,连续略过m-1个表元,第m-1个表元的后继表元是第m个表元,将该表元从环中退出。接着再次从下一个表元出发,重复以上过程,直至环中表元都退出为止。
程序:
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 //定义表中表元 5 struct ele{ 6 int no; //表元的编号 7 struct ele *link; //指向环的下一个表元的指针 8 }; 9 10 int main() 11 { 12 int n,m,i; 13 struct ele *h; //表头指针 14 struct ele *u; //用于指向表中下一个表元的指针 15 struct ele *p; //用于指向第m个表元的指针 16 17 printf("Please input n&m:\n"); 18 scanf("%d%d",&n,&m); 19 20 h = (struct ele *)malloc(sizeof(struct ele)); //形成首表元 21 u = (struct ele *)malloc(sizeof(struct ele)); 22 h->no = 1; 23 /*形成剩下的n-1个表元*/ 24 for(i=2; i<=n; i++) 25 { 26 u->link = (struct ele *)malloc(sizeof(struct ele));//为下一个表元分配一个地址 27 u = u->link; //将u指向先一个表元 28 u->no = i; 29 } 30 u->link = h; //末表元后继首元,形成环 31 puts("\nThe numbers of who will quit the cycle in turn are:"); 32 while(n) 33 { 34 for(i=1; i<m; i++) //掠过m-1个表元 35 u=u->link; 36 p = u->link; 37 u->link = p->link; 38 printf("%4d",p->no); 39 free(p); 40 n--; 41 } 42 printf("\n\n Press any key to quit...\n"); 43 44 //printf("Hello world!\n"); 45 return 0; 46 }