这个问题算是比较经典的了吧,至少我刚学编程的时候就经常看到。最近又经常看到这个问题,就写了一下,算是怀旧的我老题重温吧,其实问题还是比较简单的。
问题描述:n 个人围成一圈报数,报到 m 的人出列,要求计算删除顺序,并找到最后剩下的那个人。
分析:问题的关键有两点:
一是围成了一个圈,那么报数的时候就要考虑到循环遍历。
二是被删除的人的表示问题:①如果是数组实现的话,那么就应该是对删除的人做标记,表示其已经被删除,否则你就需要每删除一个人,就要将所有后面的人的位置都向前挪一位;②如果是链表实现的话,那么你删除的时候直接删除表示该人的节点就好。
解答:下面的代码使用数组实现,比较简单。但是思路应该比较清晰了。
/** * n人成圈问题 * 详细描述: * n 个人围成一圈报数,报到 m 的人出列,找到最后剩下的那个人。 * 思路: * 先将所有人进行编号,如果被删除就将其编号设置为0。 * 循环直到队列中只剩1个人 */ #include <stdio.h> int main(void) { int n;//总人数 int m;//用来去除人的那个数 int remain;//剩余人数 int a[100]; //用来保存人 int i;//循环临时变量 //输入人数,并初始化数组 printf("input the number of people: "); scanf("%d",&n); for(i=0; i<n; i++) a[i]=i+1; //输出所有人 printf("the index of people: /n"); for(i=0; i<n; i++) printf("%5d",a[i]); printf("/n/n"); //输入要删除的数字号码 printf("input the number you want to delete: "); scanf("%d", &m); printf("/n"); //依次删除,并打印删除过程 remain=n; int count=0;//依次计数 printf("the sequence to delete people: /n"); while(remain>1) { for(i=0; i<n; i++) { if(a[i]!=0) { count++; if(count == m) { printf("%5d",a[i]);//打印被删除的人 a[i]=0; count=0; remain--; } } } } printf("/n/n"); //打印最后剩下的人 for(i=0; i<n; i++) { if(a[i]!=0) { printf("the last people: %d/n",a[i]); } } return 0; }
本文链接:http://blog.csdn.net/daheiantian/archive/2011/02/27/6452530.aspx