约瑟夫问题C语言实现
题目内容:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。
输入格式:输入包含两个整数,第一个是n,第二个是m (0 < m,n <=300)。
输出格式:输出包含一行,即最后猴王的编号。
输入样例:18 2
输出样例:5
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct Lnode//定义循环链表结点
{
unsigned int id;
struct Lnode *next;
}Lnode,*LinkList;
void CreateCList(LinkList l,int n);//建立链长为n的循环链表
void Delete(LinkList l,int n,int m);//删去数到m的元素
void CreateCList(LinkList l,int n)//l为头结点,不存储数据,仅方便遍历
{
LinkList p;
l->next=l;
int i;
for (i=n;i>=1;i--)
{
p=(LinkList)malloc(sizeof(Lnode));
p->id=i;
p->next=l->next;
l->next=p;
}
}
void Delete(LinkList l,int n,int m)
{
int t=1,i=0;
LinkList p,pre;
pre=l;
p=pre->next;
while(i<n-1)
{
if (p==l)//若p指向头结点,不做任何操作,直接跳过
{
pre=p;
p=p->next;
}
if(m==t)//数到m,删除此结点
{
i++;
pre->next=p->next;
p=pre->next;
t=1;
}
else
{
pre=p;
p=p->next;
t++;
}
}
}
void Disp(LinkList l)//输出猴王结点
{
LinkList p;
p=l->next;
while(p!=l)
{
printf("%d",p->id);
p=p->next;
}
}
int main(int argc, char *argv[]) {
int m,n;
scanf("%d %d",&n,&m);
LinkList l;
l=(LinkList)malloc(sizeof(Lnode));
CreateCList(l,n);
Delete(l,n,m);
Disp(l);
return 0;
}