n个人,编号1,2,。。。n,从头开始报数,报到m的人出列,然后从下一个人重新开始报数,直至到最后一个人,求最后一个人出列的时其原始的序号。
1、用链表
步骤:
1构建循环链表,数据域为序号
2遍历循环链表(p->next!=p),利用k计数,当k=m,则将m对应的结点删除掉,继续遍历
3当只剩一个结点,p->next=p,将p->num输出
#include<stdio.h>
#include<malloc.h>
typedef struct node{
int num;
node *next;
}node;
node *creat(int n){ //构建循环链表
node *head,*p,*q;
int i=1;
p=(node*)malloc(sizeof(node));
p->num=i;
head=p;
for(i=2;i<=n;i++){
q=(node*)malloc(sizeof(node));
q->num=i;
p->next=q;
p=p->next;
}
q->next=head; //首尾相连
return head;
}
node*find_last_out(node* head,int m){
node* s,*p,*q;
int k=1; //计数
p=head;
while(p->next!=p){ //遍历至只剩一个结点
while(k!=m){ //m表示要数到的数
q=p;
p=p->next;
k++;
}
if(k==m){
k=1;
s=p;
q->next=p->next;
p=p->next;
printf("s->num: %d\n",s->num);
free(s);
}
}
if(p->next=p){
printf("%d",p->num);
}
return p;
}
void main(){
node* head;
head=creat(7);
head=find_last_out(head,3);
printf("head->num: ",head->num);
}
2.非递归方法:
#include<stdio.h>
#include<assert.h>
void main(){
int m,n;
int i;
scanf("%d,%d",&n,&m);
assert(m&&n);
int r=0;
for(i=2;i<=n;i++){
r=(r+m)%i;
}
printf("%d",r+1);
}
3.递归式
#include<stdio.h>
int find_last_out(int n,int m){
if(n==1)
return 0;
else
return ((m+find_last_out(n-1,m))%n);
}
void main()
{
int m,n;
int res;
scanf("%d,%d",&n,&m);
res=find_last_out(n,m)+1;
printf("%d\n",res);
}
参考:http://www.cnblogs.com/cnyao/archive/2009/10/31/Question1.html
http://blog.youkuaiyun.com/a725sasa/article/details/11664375
http://blog.youkuaiyun.com/a725sasa/article/details/11664375