1.率先,我们先来询问一下什么是Joseph环难题:

讲一个比较好玩的故事:Joseph是犹太军队的一个大将,在抵御拉各斯的起义中,他所辅导的军事被克服,只剩余残余的军旅40余人,他们都是坚强的人,所以不愿投降做叛徒。一群人决定说要死,所以用一种政策来先后杀死所有人。 
于是Joseph提议:每便由其他四个人同台杀掉一个人,而被杀的人的先后顺序是由抽签决定的,Joseph有策略地抽到了最终一签,在杀了除去他和剩下那家伙之外的终极一人,他劝服了其它一个没死的人投降了布达佩斯。

 

浓密浅出的话就是:

依据如下规则去杀人:

  • 所有人围成一圈
  • 顺时针报数,每一趟报到3的人将被杀掉
  • 被杀掉的人将从房间内被移走
  • 下一场从被杀掉的下一个人再也报数,继续报3,再清除,直到剩余一人

那就是说程序完结为:

  链表的定义: 定义为编号即可 所以data项为int

  

typedef struct NODE{
    struct NODE *next;
    int data;
}Node,*Linklist;

 

鉴于是循环,直到最终一个人, 所有可以动用异乎平日的链表: 循环链表。
当链表中只剩下一个要素后,便觉得完事了。 即 L->next = L;

#include <stdio.h>
#include <stdlib.h>
#include "Linklist.h"

void Print_Linklist(Linklist L)
{
    Linklist head = L;
    printf("List: ");
    while(L->next != head)
    {
        printf("%d ",L->data);
        L = L->next;
    }
    printf("%d ",L->data);
    printf("\n");
}

int main()
{
    int i;
    Linklist L;
    Linklist head;
    Linklist Out;
    L = (Node*)malloc(sizeof(Node));
    head = L;
    L->data = 1;
    L->next = head;
    for(i=2;i<=41;i++)
    {
        L->next=(Node*)malloc(sizeof(Node));
        L->next->data = i;
        L->next->next = head;
        L = L->next;
    }
    Print_Linklist(head);
    L = head;
    while(L != L->next)
    {
         for(i=1;i<2;i++)
         {
             L = L->next;
         }
         Out = L->next;
         printf("%2d号 ----> 自杀!\n",Out->data);
         L ->next = Out->next;
         L = L->next;
         free(Out);
    }
    printf("幸存者是:%d",L->data);
    return 0;
}

澳门金沙国际 1

1.率先,我们先来打探一下什么样是Joseph环难点:

后天看了眨眼之间间Joseph难点,嗯,感觉自己智商欠费:( 如故来计算下好啦~

正文实例讲述了PHP已毕的根据单向链表解决Joseph环难题。分享给大家供我们参考,具体如下:

讲一个比较有意思的故事:Joseph是犹太军事的一个将军,在对抗亚特兰大的起义中,他所指引的枪杆子被粉碎,只剩余残余的武力40余人,他们都是钢铁的人,所以不愿投降做叛徒。一群人决定说要死,所以用一种政策来先后杀死所有人。
于是Joseph提议:每便由其他四个人一头杀掉一个人,而被杀的人的先后顺序是由抽签决定的,Joseph有机关地抽到了最后一签,在杀了除了她和剩余那家伙之外的最后一人,他劝服了别的一个没死的人投降了埃及开罗。

问题

Joseph是犹太军事的一个大将,在抵抗休斯敦的起义中,他所指引的部队被克制,只剩余残余的队伍容貌40余人,他们都是坚强的人,所以不愿投降做叛徒。一群人决定说要死,所以用一种政策来先后杀死所有人。
于是Joseph提出:每一次由别的五个人同台杀掉一个人,而被杀的人的先后顺序是由抽签决定的,Joseph有谋略地抽到了最后一签,在杀了除了她和剩余那个家伙之外的尾声一人,他劝服了此外一个没死的人投降了班加罗尔。

咱俩以此规则是那般定的:
在一间房间总共有n个人(下标0~n-1),只可以有最后一个人活命。

鲁人持竿如下规则去杀人:
所有人围成一圈
顺时针报数,每一回报到q的人将被杀掉
被杀掉的人将从房间内被移走
然后从被杀掉的下一个人重复报数,继续报q,再清除,直到剩下一人

Joseph环难题:在达拉斯人攻克乔塔帕特后,39
个犹太人与Josephus及她的意中人躲到一个洞中,39个犹太人决定宁愿死也绝不被仇人抓到,于是决定了一个自杀方式,41私房排成一个圆形,由第1个人初叶报数,每报数到第3人该人就无法不自杀,然后再由下一个双重报数,直到所有人都自杀身亡截至。可是约瑟夫us
和他的爱人并不想遵循。首先从一个人早先,越过k-2个人(因为第二个体已经被通过),并杀死第k个体。接着,再越过k-1个人,并杀死第k私家。这几个历程沿着圆圈平昔开展,直到最后只剩余一个人留下,这厮就足以两次三番活着。难题是,给定了和,一开端要站在怎么地点才能制止被处决?Josephus要他的对象先假装遵循,他将对象与友爱配置在第16个与第31个地点,于是逃过了本场寿终正寝游戏。

深切浅出的话就是:

输入

人的个数 : n
历次报到q 就会被杀死 的 q

更加多的接近难点是:n个人围成圈,依次编号为1,2,..,n,现在从1号起始逐项报数,当报到m时,报m的人脱离,下一个人重新从1报起,循环下去,问最终剩余那个人的数码是多少?

安份守己如下规则去杀人:
所有人围成一圈
顺时针报数,每一遍报到3的人将被杀掉
被杀掉的人将从房间内被移走
然后从被杀掉的下一个人重复报数,继续报3,再清除,直到剩下一人

输出

末尾可以活下来的人的下标

代码完毕:

那就是说程序落成为:

有关分析

1、https://blog.csdn.net/tingyun\_say/article/details/52343897
2、http://www.cnblogs.com/kkrisen/p/3569281.html\#undefined

<?php
class Node{
  public $value;   // 节点值
  public $nextNode;  // 下一个节点
}
function create($node, $value){
  $node->value = $value;
}
function addNode($node, $value){
  $lastNode = findLastNode($node);
  $nextNode = new Node();
  $nextNode->value = $value;
  $lastNode->nextNode = $nextNode;
}
/* 找到最后的节点 */
function findLastNode($node){
  if(empty($node->nextNode)){
    return $node;
  }else{
    return findLastNode($node->nextNode);
  }
}
/* 删除节点 必须head为引用传值 */
function deleteNode(&$head, $node, $m, $k = 1){
  if($k + 1 == $m){
    if($node->nextNode == $head){
      $node->nextNode = $node->nextNode->nextNode;
      $head = $node->nextNode;
      return $node->nextNode;
    }else{
      $node->nextNode = $node->nextNode->nextNode;
      return $node->nextNode;
    }
  }else{
    return deleteNode($head, $node->nextNode, $m, ++$k);
  }
}
/* 节点数 */
function countNode($head, $node, $count = 1){
  if($node->nextNode == $head){
    return $count;
  }else{
    return countNode($head, $node->nextNode, ++$count);
  }
}
function printNode($head, $node){
  echo $node->value . ' ';
  if($node->nextNode == $head) return;
  printNode($head, $node->nextNode);
}
function show($data){
  echo '<pre>';
  print_r($data);
  echo '</pre>';
}
$head = new Node();
create($head, 1);
addNode($head, 2);
addNode($head, 3);
addNode($head, 4);
addNode($head, 5);
addNode($head, 6);
addNode($head, 7);
addNode($head, 8);
addNode($head, 9);
addNode($head, 10);
addNode($head, 11);
addNode($head, 12);
$lastNode = findLastNode($head);
$lastNode->nextNode = $head;
$count = countNode($head, $head);
$tmpHead = $head;
while ($count > 2) {
  $tmpHead = deleteNode($head, $tmpHead, 3, 1);
  $count = countNode($head, $head);
}
printNode($head, $head);

链表的定义: 定义为编号即可 所以data项为int

分析

首先次报数杀掉的是下标为(q-1)人
C语言链表完结,Joseph难点。q       0
q+1     1
:       :
:        :
n-1     n-q-1
0      n-q
1      n-q+1
:        :
:        :
q-2     n-2

由上述可知,杀掉一个人后,重新组成了一个约瑟夫环,重新整合的Joseph环的下标和事先的下标关系为
f(n)=(f(n-1)+q)%n。当最终只剩余一个人的时候,它的下标为0,我们可由上述的递推关系取得只剩余四人时它的下标,然后再推得只剩余3个人时它的下标,平昔推到最终有n个人时,它的下标,就获得了最后的结果。请注意,那样的解法所获取的坐标是从以0–(n-1)为标准的,假如想获取以1–n为基准下的,直接将所得的结果加1就好了,很直观的讲演就是将下标值加1。
另一个诠释:
f(1, 1) = 1;
f(n, k) = (f(n-1, k) + k – 1)%n + 1;

#include "stdafx.h"
#include <iostream>
using namespace std;

int main()
{
    int n, q;
    cin >> n >> q;
    if (n == 0)
        return 0;
    int result = 0;
    for (int i = 2; i <= n; i++)
        result = (result + q ) % i;

    return result+1;
}

更加多关于PHP相关内容感兴趣的读者可查阅本站专题:《PHP数据结构与算法教程》、《PHP基本语法入门教程》、《php面向对象程序设计入门教程》、《php字符串(string)用法总括》及《php程序设总结法计算》

typedef struct NODE{
    struct NODE *next;
澳门金沙国际 ,    int data;
}Node,*Linklist;

转变难点

poj上有个转移难题,题材链接:http://poj.org/problem?id=3517,那一个题与经典Joseph难题的分裂是,它要求首先个干掉的人下标为m,并且下标从1方始。对于那几个标题的求解,大家可以听从原来方式去做,得到结果后再去运动下标。在原来的标题中,第三个干掉的人下标为q,大家想艺术运动下标使得第三个干掉的人由q变为m,如果n=5,q=2,m=4,
那么原始种类为
1, 2, 3,4,5
只要使得第五次杀死的人为m, 那么序列应为
3 , 4 , 5 ,1 , 2
那么由地点的什么得到上面的结果
f(下)= (f(上)+m-k)%n

// yuesefu.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
using namespace std;

int main()
{
    int n, q, m;
    cin >> n >> q>> m;
    if (n == 0)
        return 0;
    int mid = 0;
    for (int i = 2; i <= n; i++)
        mid = (mid + q ) % i;
    int result = 0;
    result = (mid + 1 + m - q) % n;
    if (result < 0) result = result + n;
    return result;
}

企望本文所述对大家PHP程序设计有着支持。

出于是循环,直到最终一个人, 所有可以选用异乎平常的链表: 循环链表。
当链表中只剩余一个元素后,便觉得完事了。 即 L->next = L;

留个坑

1、打印每一遍淘汰的人
https://blog.csdn.net/coder\_pig/article/details/50268099
2、如何用python实现?

index, step = 0, 3    
while len(a) > 1:
    index = (index + step - 1) % len(a)    
    print('kill No.', a[index])
    del a[index]
print('\nWinner is', a[0])

你或许感兴趣的稿子:

  • php解决Joseph环示例
  • php完结Joseph难题的情势小结
  • Joseph环难题的PHP已毕使用PHP数组内部指针操作函数
  • phpJoseph难点一蹴而就有关镇压犯人的算法
  • PHP使用栈解决Joseph环难题算法示例
  • PHP基于递归完成的Joseph环算法示例
  • PHP完结Joseph环难点的不二法门分析
  • PHP基于关联数组20行代码搞定Joseph难点示例
  • php基于环形链表解决Joseph环难题示例
  • PHP环形链表完成格局言传身教
  • php使用环形链表解决Joseph难点完全示例

#include <stdio.h>
#include <stdlib.h>
#include “Linklist.h”

void Print_Linklist(Linklist L)
{
    Linklist head = L;
    printf(“List: “);
    while(L->next != head)
    {
        printf(“%d “,L->data);
        L = L->next;
    }
    printf(“%d “,L->data);
    printf(“\n”);
}

int main()
{
    int i;
    Linklist L;
    Linklist head;
    Linklist Out;
    L = (Node*)malloc(sizeof(Node));
    head = L;
    L->data = 1;
    L->next = head;
    for(i=2;i<=41;i++)
    {
        L->next=(Node*)malloc(sizeof(Node));
        L->next->data = i;
        L->next->next = head;
        L = L->next;
    }
    Print_Linklist(head);
    L = head;
    while(L != L->next)
    {
        for(i=1;i<2;i++)
        {
            L = L->next;
        }
        Out = L->next;
        printf(“%2d号 —-> 自杀!\n”,Out->data);
        L ->next = Out->next;
        L = L->next;
        free(Out);
    }
    printf(“幸存者是:%d”,L->data);
    return 0;
}

澳门金沙国际 2

正文永久更新链接地址

澳门金沙国际 3

相关文章