丢手帕问题(约瑟夫问题)

来源:互联网 发布:大屏电子书阅读器 知乎 编辑:程序博客网 时间:2024/05/16 18:59

这是17世纪的法国数学家加斯帕在《数目的游戏问题》中讲的一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。
*问题分析与算法设计*
约瑟夫问题并不难,但求解的方法很多;题目的变化形式也很多。这里给出一种实现方法。
题目中30个人围成一圈,因而启发我们用一个循环的链来表示。可以使用结构数组来构成一个循环链。结构中有两个成员,其一为指向下一个人的指针,以构成环形的链;其二为该人是否被扔下海的标记,为1表示还在船上。从第一个人开始对还未扔下海的人进行计数,每数到9时,将结构中的标记改为0,表示该人已被扔下海了。这样循环计数直到有15个人被扔下海为止。这个是愿意。

现在的衍生问题

就是说有n个人围成一圈,然后说从任意指定的一个
人那里为起点,以m个人为单位,每转m个人第m个人被杀死。当起始人也就是所谓的
第1个人是最后被杀死的,这个m就是为所求,满足这样就叫joseph问题。

程序1:

#include "stdio.h"
#include <stdlib.h>
void Josephus(int n,int m);   //使用带表头附加结点的循环单链表接决约瑟夫问题

struct Lnode
{
 int data;
 struct Lnode *next;
};
typedef struct Lnode LNode;

int main()
{
 int n,m;
 printf("input the total number/n");
 scanf("%d",&n);
 printf("input the number to call/n");
 scanf("%d",&m);
 Josephus(n,m);
 return 0;

}

void Josephus(int n,int m)   //使用带表头附加结点的循环单链表接决约瑟夫问题
{
 int i;
 LNode *HL=(LNode *)malloc(sizeof(LNode));  //生成表头附加结点,此时循环单链表为空
 HL->next=HL;
 LNode *cur=HL;
 for(i=n;i>=1;i--)  //生成含有n个结点的,结点值依次为1-n的带表头附加结点的循环表
 {
  LNode *newptr=(LNode *)malloc(sizeof(LNode));   //生成新结点
  newptr->data=i;     
  newptr->next=HL->next;    //把新结点插入到表头
  HL->next=newptr;
 }
 while(cur->next!=cur)//最后剩下的cur
 {
  for(i=1;i<m;i++)
  {
   cur=cur->next;
   if(cur==HL)
   {
    cur=cur->next;
   }
  }
  if(cur->next==HL)
   cur=cur->next;
  printf("%d/t",cur->next->data);
  {
   LNode *temp;
   temp=cur->next;
   cur->next=cur->next->next;
   free(temp);
  }
 }
 putchar('/n');
}
程序2:

#include<iostream.h>
#include<stdlib.h>
void make(int *base,int n,int pos,int c,int m)//参数的意义。base数组名,n数组长度。pos跑格的一个东西。c计算次数的。m每次跑路的长度。
{
    int j=0;
    cout<<"NO. "<<++c<<" 第"<<pos+1<<"位出列"<<endl;//输出
    base[pos]=0;//踢掉
    if(c==n)return;  //出口
    while(j-m)if(base[pos=(pos+1)%n])j++;//递归点 ,每次数到几这个3就改到几
    make(base,n,pos,c,m);//递归
}
int main()
{
    int n,m,c=0,pos;//从N开始数,则把pos改为N-1就行了.
    cout<<"请输入总人数"<<endl;
    cin>>n;
 cout<<"请输入要隔几个人:"<<endl;
 cin>>m;
    int *base=new int[n];
    for(int i=0;i<n;i++)base[i]=1;
 pos=m-1;
    make(base,n,pos,c,m);
    delete[]base;
    system("PAUSE");
    return 0;
}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 眼睛有东西磨眼怎么办 怀孕了眼睛肿疼怎么办 眼睛疼又红血丝怎么办 用眼过度眼睛疼怎么办 眼睛玩手机视力下降怎么办 看手机眼睛疼该怎么办 眼睛眨一下就痛怎么办 着火了怎么办教案详案 汽车尾灯磕破了怎么办 后尾灯灯罩裂了怎么办 七氟丙烷喷伤了怎么办 冒险岛2fps低怎么办 虐杀原形2很卡怎么办 玩虐杀原形2卡怎么办 虐杀原形2闪退怎么办 电脑显示不出u盘怎么办 电脑不显示u盘怎么办 u盘在电脑不显示怎么办 笔记本不识别u盘怎么办 u盘突然识别不了怎么办 xp电脑读不出u盘怎么办 电脑无法读取u盘怎么办 win7电脑不读u盘怎么办 电脑识别不出u盘怎么办 u盘电脑读不出来怎么办 u盘突然无法识别怎么办 u盘电脑无法识别怎么办 系统无法识别u盘怎么办 手机u盘无法识别怎么办 u盘无法被识别怎么办 电脑不能读取u盘怎么办 电脑装系统卡了怎么办 怀孕三个月胚胎停育怎么办 被蟑螂咬了怎么办图片 有家人进了传销怎么办 有亲人进了传销怎么办 误入传销违法了怎么办 tt游戏账号忘了怎么办 被臭蚊子咬了怎么办 狗狗鼻子掉皮了怎么办 火碱弄到皮肤上怎么办