约瑟夫(josephus)环是这样的:假设有n个小孩坐成一个环,假如从第一个小孩开始数,如果数到m个小孩,则该小该离开,问最后留下的小孩是第几个小孩?例如:总共有6个小孩,围成一圈,从第一个小孩开始,每次数2个小孩,则游戏情况如下:
小孩序号:1,2,3,4,5,6
离开小孩序号:2,4,6,3,1
最后获胜小孩序号:5
这样的问题,我可以先考虑输入的内容有哪些?输出内容有哪些?
要求用户输入的内容有:
1、是小孩的个数,也就是n的值;
2、是离开小孩的间隔是多少?也就是m的值。
3、所有小孩的序号要求存在数组或者链表中,所以需要定义一个指针,这里我们用数组来存放小孩的序号。
而要求输出的内容是:
1、离开小孩的序号;
2、最后留下小孩的序号;
我写的:
/****Josephus.h*****/
#include "StdAfx.h"
struct LinkList;
typedef struct LinkList* pLinkList;
/****Josephus.cpp*****/
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include "Josephus.h"
struct LinkList
{
int value;
pLinkList next;
};
pLinkList Create( int N )
{
pLinkList pHead,pNode,current;
if ( N<=0 )
{
printf( "孩子数目至少为一个\n");
return NULL;
}
else
{
pHead=(pLinkList)malloc(sizeof(struct LinkList));
pHead->value=1;
pHead->next=NULL;
current = pHead;
for (int i=1;i<N;i++)
{
pNode=(pLinkList)malloc(sizeof(struct LinkList));
pNode->value = i+1;
pNode->next = NULL;
current->next = pNode;
current = pNode;
}
}
return pHead;
}
int Josephus(pLinkList child , int n, int m )
{
int i,j=n;
pLinkList pNode = child , pre = NULL ,pTemp ;
while (j>1)
{
i=m-1;
while ( i > 0 ) //find which child
{
if ( pNode->next )
{
pre = pNode;
pNode = pNode->next;
i--;
}
else
{
pre = NULL;
pNode = child;
i--;
}
} //end while
if ( !pre ) //pre == NULL
{
pTemp = child;
child = child->next;
pNode = child;
free(pTemp);
j--;
}
else
{
pTemp = pNode;
if ( !pNode->next)
{
pre->next = NULL;
pNode = child;
}
else
{
pre->next = pNode->next;
pNode = pNode->next;
}
free( pTemp );
j--;
}
}
return child->value;
}
int main(int argc, char* argv[])
{
int n,m;
pLinkList pHead;
printf("请输入孩子个数:\n");
scanf("%d",&n);
pHead=Create( n );
printf("请输入每次数的个数:\n");
scanf("%d",&m);
int result = Josephus(pHead,n,m);
printf("%d\n",result);
return 0;
}