/**************************************************************************************
* Function : 约瑟夫问题
* Create Date : 2014/04/20
* Author : NTSK13
* Email : beijiwei@qq.com
* Copyright : 欢迎大家和我一起交流学习,转载请保持源文件的完整性。
任何单位和个人不经本人允许不得用于商业用途
* Version : V0.1
***************************************************************************************
题目:
约瑟夫问题
有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出
圈子,问最后留下的是原来第几号的那位
分析:
//My anser:
常规解法,模拟数数自杀过程。自杀的人下次数数直接跳过。
**************************************************************************************/
#include<stdio.h>
#define MY_FUNC 1
#if MY_FUNC
#define N 3//数到3
#define M 41
int data[]={0};
int remain(int n);
//the first solution:
int main()
{
int ret=0;
ret=remain(M);
printf("The last remain number is: %d \n",ret);
fflush(stdout);//修复Eclipse printf()不能显示的小bug
return 0;
}
int remain(int n)
{
int i=0,j=0,die=0;
int current=1,k=1;
for(j=0;j<n;j++)
data[j]=j+1;
while(die<n)
{
if(current==N+1)//顺序数数123,123,....
current=1;
if(current==N)//数到3的时候,要移除一个不为0的数,为0 代表人已自杀死去
{
j=i;
if(j>n)
j=j%n;
while(1)//remove a death
{
if(data[j]!=0)
{
data[j]=0;
printf("第%d个死去的人编号是: %d \n",k++,j+1);
fflush(stdout);
die++;
break;
}
else
{
j++;
if(j==n)
j=0;
}
}
if(die==n)
break;
}
else//数数序列号不为3的时候,继续数数,但是要跳过死去的人
{
while(1)//jump death
{
if(data[i]!=0)
break;
else
{
i++;
if(i==n)
i=0;
}
}
}
current++;//计数加一
i++; //
if(i==n)
i=0;
}
return j+1;
}
#else
/************************************************************************************/
//the second solution:
#include <stdio.h>
#include <stdlib.h>
#define N 41
#define M 3
int main()
{
int man[N]={0};
int count=1;
int i=0,pos=-1;
int alive=0;
while(count<=N)
{
do{
pos=(pos+1) % N; //环状处理
if(man[pos]==0)
i++;
if(i==M) //报数3的人
{
i=0;
break;
}
}while(1);
man[pos]=count;
count++;
}
printf("\n约瑟夫排列(最初位置-约瑟夫环位置):\n");
fflush(stdout);
for(i=0;i<N;i++)
{
printf("%d-%d ",i+1,man[i]);
fflush(stdout);
if(i!=0 && i%10==0) //每输出10个则换行
{
printf("\n");
fflush(stdout);
}
}
printf("\n\n请输入准备剩下的人数:\n");
fflush(stdout);
scanf("%d", &alive);
printf("这%d人初始位置应排在以下序号:\n",alive);
fflush(stdout);
alive=N-alive;
for(i=0;i<N;i++)
if(man[i]>alive)
{
printf("初始序号:%d,约瑟夫环序号:%d\n",i+1,man[i]);
fflush(stdout);
}
printf("\n");
fflush(stdout);
getch();
return 0;
}
#endif
经典算法之约瑟夫问题
最新推荐文章于 2019-10-11 19:54:48 发布