题目描述:
一群猴子要选新猴王。新猴王的选择方法是:让N只候选猴子围成一圈,从某位置起顺序编号为1~N号。从第1号开始报数,每轮从1报到3,凡报到3的猴子即退出圈子,接着又从紧邻的下一只猴子开始同样的报数。如此不断循环,最后剩下的一只猴子就选为猴王。请问是原来第几号猴子当选猴王?
输入格式:
输入在一行中给一个正整数N(≤1000)。
输出格式:
在一行中输出当选猴王的编号。
输入样例:
在这里给出一组输入。例如:
11
输出样例:
在这里给出相应的输出。例如:
7
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct qq{
int k;
struct qq *next;
}az;
az *create(int n){//排好队,用循环链表
az *p=(az *)malloc(sizeof(az)),*tail=p;
p->k=1;
p->next=NULL;
for(int i=2;i<=n;i++){
az *q=(az *)malloc(sizeof(az));
q->k=i;
q->next=NULL;//每次末结点的next置为NULL,防止最后忘记
tail->next=q;
tail=tail->next;
}
tail->next=p;//形成闭环
return p;//返回第1号猴子的地址
}
int test(az *p,az *q,az *o){//实现主要功能
if(q->next==q){
return q->k;//递归出口
}else{
q=p->next;
p=q->next;
q=p->next;
o=o->next;//o指针指向被淘汰的猴子的上一个(如果是双链表就不需要)
free(p);//淘汰
o->next=q;//连接
p=q;o=q;
return test(p,q,o);
}
}
int main(){
int n;
scanf("%d",&n);
az *p=create(n),*q=p,*o=p;
int d=test(p,q,o);
printf("%d",d);
return 0;
}
总结:
这道题可以用数组来实现,效率会更高。比如定义int a[2][MAXN];第0行存储猴子编号,第1行先初始化为0,表示没有被out,淘汰之后赋值为1,最后会剩下一列的数据的第1行为0,其余为1,这样就实现了找到猴王的功能。