基础算法1——约瑟夫问题

问题来历

据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。

17世纪的法国数学家加斯帕在《数目的游戏问题》中讲了这样一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。

分析1:

(1)由于对于每个人只有死和活两种状态,因此可以用布朗型数组标记每个人的状态,可用true表示死,false表示活。

(2)开始时每个人都是活的,所以数组初值全部赋为false。

(3)模拟杀人过程,直到所有人都被杀死为止。

C++代码:

 1 #include<iostream>
 2 using namespace std;
 3 int main()
 4 {
 5     bool a[101]={0};
 6     intn,m,i,f=0,t=0,s=0;
 7     cin>>n>>m;
 8     do
 9     {
10         ++t;//逐个枚举圈中的所有位置
11         if(t>n)
12         t=1;//数组模拟环状,最后一个与第一个相连
13         if(!a[t])
14         s++;//第t个位置上有人则报数
15         if(s==m)//当前报的数是m
16         {
17             s=0;//计数器清零
18             cout<<t<<‘‘;//输出被杀人编号
19             a[t]=1;//此处人已死,设置为空
20             f++;//死亡人数+1
21         }
22     }while(f!=n);//直到所有人都被杀死为止
23     return 0;
24 }

C代码:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3
 4 typedef struct node
 5 {
 6     int data;
 7     struct node *next;
 8 }Node;
 9
10 Node *creat(int n)
11 {
12     Node *p, *head;
13     head = (Node *)malloc(sizeof(Node));
14     p = head;
15     Node *s;
16     int i = 0;
17
18     if(0 != n)
19     {
20     while(i <= n)
21     {
22         s = (Node *)malloc(sizeof(Node));
23         s->data = i++;
24             p->next = s;
25         p = s;
26     }
27     s->next = head->next;
28     }
29     free(head);
30     return s->next;
31 }
32
33 int main()
34 {
35     int n = 41, m = 3;
36     int i;
37     Node *p = creat(n);
38     Node *temp;
39
40     m %= n;
41
42     while(p != p->next)
43     {
44         for(i = 1; i < m-1; i++)
45     {
46         p = p->next;
47     }
48     printf("%d ", p->next->data);
49     temp = p->next;
50     p->next = temp->next;
51
52     free(temp);
53     p = p->next;
54     }
55     printf("%d\n", p->data);
56
57     return 0;
58 }
时间: 2024-08-11 12:42:52

基础算法1——约瑟夫问题的相关文章

基础算法之排序--快速排序

1 /************************************************************************************** 2 * Function : 快速排序 3 * Create Date : 2014/04/21 4 * Author : NTSK13 5 * Email : [email protected] 6 * Copyright : 欢迎大家和我一起交流学习,转载请保持源文件的完整性. 7 * 任何单位和个人不经本人允许不

九章算法 基础算法 强化算法 系统设计 大数据 安卓 leetcode 高清视频

leetcode 直播视频讲座录像 九章算法视频录像,PPT 算法班,算法强化班,Java入门与基础算法班,big data项目实战班,Andriod项目实战班 九章算法下载 九章算法面试 九章算法leetcode 九章算法答案 九章算法mitbbs 九章算法班 九章算法ppt 九章算法录像 九章算法培训 九章算法微博 leetcode 视频 九章算法偷录 算法培训 算法班课程大纲: 1 从strStr谈面试技巧与Coding Style(免费试听) 2 二分搜索与旋转排序数组 Binary S

算法录 之 基础算法

这一篇文章主要说说一些基础算法,这些算是很多其他算法的基石. 主要包括  模拟,暴力,枚举,递归,贪心,分治. 1,模拟: 顾名思义,模拟就是...饿,模拟,有一些题目就是给你一些步骤,然后你写代码一步步去模拟那些步骤就行.这类题目主要属于基础题,但是当然如果需要模拟的步骤足够恶心的话,还是比较麻烦的... 具体模拟的例子在之后的练习中会遇到的,按照题目要求一步步做就行,一般算法难度比较小. 2,暴力: 顾名思义,暴力就是...饿,暴力.比如说题目让从平面上的10个点中取三个点,让他们形成的三角

算法:约瑟夫环问题

算法:约瑟夫环问题 [写在前面] 由于本人天生驽钝,所写代码和描述可能不堪入目,高手请移步.但是我一直在努力记录一下有用的知识点,给自己给朋友用,只是希望对大家有帮助. [问题描述] 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从第一个人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,求最后一个出圈的人的标号. [代码] void JOSEF(int n,int m) //:n个人

最最最最最最最最基础的C---C简介和基础算法

C简介 C是一门程序设计语言,面向过程的语言.于1972至1973年设计出来的语言. C具有32个关键字,9种控制语句,34种运算符. 函数是C的基本单位:一个C程序的执行总是从main函数开始的. C程序运行步骤:源程序--编译-->目标文件--执行-->可执行目标程序. 基础算法 完整的程序设计=数据结构+算法+程序设计方法+语言工具 算法特效: 1.有穷性:一个算法包含有限的操作步骤 2.确定性:确定算法的每一个步骤都是确定的 3.有零个或多个输入 4.有一个或多个输出 5.有效性:算法

基础算法

c语言基础算法大全 冒泡排序 选着排序 插入排序 快速排序 shell排序. 合并排序. 下面是各个排序算法的实现: 冒泡排序 void bobuleSort(int a[], int len) { int i,j,flag =1; for(i = 0; i<len; i++) { for(int j =len-1; j>i; j--) { if(a[j] <= a[i]) { int tmp = a[j]; a[j] = a[i]; a[i] = tmp; flag = 0; } }

复习基础算法的感想

晚上做杭电OJ,第二题是一个比较直观的题,我也是太直观了.贴出代码,供自己反省,从7点15分一直做到结束,wa9次....orz....看来自己的算法功底还差的很远很远. 接下的几天,学习大白上的基础 算法部分. #include<iostream> #include<stdio.h> #include<cstring> using namespace std; char a[20],b[20]; char c[20]; void shuchu(int num) { i

二叉树基础算法总结

记录一些二叉树的基础算法 二叉树节点结构: typedef struct TreeNode{ int val; struct TreeNode *left; struct TreeNode *right; }TreeNode,*Node; 1.遍历 前.中.后序递归遍历: void pre_order_traversal(TreeNode *root){ if(root! = NULL){ visit(root); pre_order_traversal(root->left); pre_ord

PHP基础算法

1.首先来画个菱形玩玩,很多人学C时在书上都画过,咱们用PHP画下,画了一半. 思路:多少行for一次,然后在里面空格和星号for一次. <?php for($i=0;$i<=3;$i++){ for($j=0;$j<=3-$i;$j++){ echo ' '; } for($k=0;$k<=2*$i;$k++){ echo '*'; } echo '<br/>'; } 2.冒泡排序,C里基础算法,从小到大对一组数排序. 思路:这题从小到大,第一轮排最小,第二轮排第二小