题目描述:
n只猴子围坐成一个圈,按顺时针方向从1到n编号。然后从第q号猴子开始沿顺时针方向从q开始报数,报到m的猴子出局,再从刚出局猴子的下一个位置重新开始报数,如此重复,直至剩下一个猴子,它就是大王。
输入:输入两个整数n和m,1<=m<=n<=100。
输出:输出猴王的编号
样例输入
7 4 3
样例输出
4
样例说明:n=7 m=4 n=3
代码思想:一共四个函数,
第一个函数:创建链表,得到头结点
第二个函数:显示链表(方便测试)
第三个函数:p,q分别指向头结点和尾节点。第一次找到尾节点(这里可以自己优化),第二次循环得到第p个猴子的位置。第三次嵌套循环,外面循环是到最后一只猴子为止,内部循环是从p开始计数一直到第m只猴子为止并将结点删除。
代码示例
#include<stdio.h>
#include<stdlib.h>
int main()
{
int m,n,p;
scanf("%d %d %d",&n,&m,&p);
printf("%d",Monkey(n,m,p));
return 0;
}
/*猴子选大王*/
//链表结构
struct linkNode{
int data;
struct linkNode *next;
};
struct linkNode* LinkList(int n);
void pri_LinkList( struct linkNode *head,int n);//打印链表
int delete_Monkey(struct linkNode *head,int m,int n,int p);//删去选中的猴子
int Monkey(int n,int m,int p);
struct linkNode* LinkList(int n){
struct linkNode *head,*p=NULL,*index=NULL;
int i;
//注意head也要
head= (struct linkNode*)malloc(sizeof(struct linkNode));
index=head;
head->data=1;
head->next=head;
for(i=2;i<n+1;i++)
{
p= (struct linkNode*)malloc(sizeof(struct linkNode));
p->data=i;
index->next=p;
index=index->next;
}
index->next=head;
return head;
}
void pri_LinkList( struct linkNode *head,int n)
{
struct linkNode *p;
p=head;
int i;
printf("猴子的顺序为:");
for(i=0;i<n;i++)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
int delete_Monkey(struct linkNode *head,int m,int n,int p){
int i,j,k;
struct linkNode *h,*q;//一个确定m的位置,两个用于删除指针
q=h=head;
//遍历到头结点的前一个结点
for(k=1;k<n;k++)
h=h->next;
// printf("h的位置为%d:\n",h->data);
//到达第p只猴子的位置
for(k=1;k<p;k++)
{
q=q->next;
h=h->next;
}
// printf("%d\n",q->data);
//遍历只剩一只猴子
for(i=n;i>2;i--)
{
//找到第m只猴子并删除
for(j=1;j<m;j++)
{
h=h->next;
q=q->next;
}
printf("除去的猴子为%d:\n",q->data);
h->next=q->next;
free(q);
q=h->next;
}
return q->data;
}
int Monkey(int n,int m,int p)
{
int index;
//创建循环链表
struct linkNode *head;
head=LinkList(n);
pri_LinkList(head,n);
index=delete_Monkey(head,m,n,p);
//遇到m个时就删除
return index;
}
输出结果:
最近在学c语言。百度了很多都是用数组写的,但是范围比较小,因此自己用链表实现。
多练习的点:创建链表不够熟练。