scheme解约瑟夫环问题

  看了javaeye上一个解决约瑟夫环的问题的帖子,就想能不能用scheme来解决。如果采用推导出的数学公式来处理当然很简单了:

(define (joseph n m)
  (define (joseph-iter init s)
    (if (> init n)
        (+ s 1)
        (joseph-iter (+ init 1) (remainder (+ s m) init))))
  (joseph-iter 2 0))

    我想是否可以用一般的模拟算法来实现?也就是模拟一个循环链表,每次删除第m个元素。弄了个比较丑陋的实现:

(define (enumrate-interval low high)
  (if (> low high)
      '()
      (cons low (enumrate-interval (+ low 1) high))))
(define (delete-last list)
  (if (eq? (cdr list) '())
      '()
      (cons (car list) (delete-last (cdr list)))))

(define (joseph-iter init list it) 
  (let ((m (remainder it (length list))))
   (cond ((= m 0) (delete-last list))
         ((= m 1) (append (cdr list) (reverse init)))
         (else
           (joseph-iter (cons (car list) init) (cdr list) (- m 1))))))
(define (joseph n m)
    (define (joseph-list list m)
      (display list) 
      (newline)
      (if (eq? (cdr list) '())
          (car list)
          (joseph-list (joseph-iter '() list m) m)))

计算(joseph 8 3)的过程如下:
(1 2 3 4 5 6 7 8)
(4 5 6 7 8 1 2)
(7 8 1 2 4 5)
(2 4 5 7 8)
(7 8 2 4)
(4 7 8)
(4 7)
(7)
7

看了这个计算过程就知道我这个方法多糟糕,每次都重新构造列表。不知道看blog的大大们有没有更好的思路?

文章转自庄周梦蝶  ,原文发布时间 2008-03-20

时间: 2025-01-24 07:04:03

scheme解约瑟夫环问题的相关文章

详解约瑟夫环问题及其相关的C语言算法实现_C 语言

约瑟夫环问题 N个人围成一圈顺序编号,从1号开始按1.2.3......顺序报数,报p者退出圈外,其余的人再从1.2.3开始报数,报p的人再退出圈外,以此类推.   请按退出顺序输出每个退出人的原序号  算法思想用数学归纳法递推. 无论是用链表实现还是用数组实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂度高达O(nm),若nm非常大,无法在短时间内计算出结果.我们注意到原问题仅仅是要求出最后的胜利者的序号,而不是要读者模拟整个过程.因此如果要追求效率,就要打破常规,实

批处理解约瑟夫环应用题代码_DOS/BAT

题目: 有二十九个女生(分别用1-29号来称呼)围成一圈玩报数游戏,规则是这样的:从1开始数数,当数到3的这个人就退出游戏,而她后面的人接着从1数...如此一直到最后剩下一个人,现在知道最初是从13号女生开始的游戏,问最后剩下的会是第几号女生? 要求: 1 用批处理解答 2 代码简洁高效 3 代码通用且不生成临时文件 加分原则: 以思路为重(如思路独特,请简要说明) 完全符合要求的加10分 已有两套解决方案,见3楼more和6楼ieutk版主的代码,但个人认为这两套方案均不完美(见本人的跟贴评述

算法问题-用c++打的约瑟夫环,为什么总是过不了

问题描述 用c++打的约瑟夫环,为什么总是过不了 #includeusing namespace std;templatestruct linknode{ T data; linknode* link; linknode(T dlinknode* next=NULL):data(d)link(next){}};templateclass list{ public: list(T x){ linknode* first=new linknode(x); first->link=first; } ~

九度题目1188:约瑟夫环

题目1188:约瑟夫环 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1500 解决:665 题目描述:     N个人围成一圈顺序编号,从1号开始按1.2.3......顺序报数,报p者退出圈外,其余的 人再从1.2.3开始报数,报p的人再退出圈外,以此类推.     请按退出顺序输出每个退出人的原序号. 输入: 包括一个整数N(1<=N<=3000)及一个整数p. 输出: 测试数据可能有多组,对于每一组数据, 按退出顺序输出每个退出人的原序号. 样例输入: 7 3 样例输出:

猴子选大王-约瑟夫环

jobdu-1188:约瑟夫环-ac 猴子选大王,如此经典的问题  

C++第15周项目3 -约瑟夫环

课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565,本周题目链接:http://blog.csdn.net/sxhelijian/article/details/9018813 [项目3]Josephus(约瑟夫环)问题 n个小孩子围成一圈,从第一个小孩子开始顺时针方向数数字,到第m个小孩子离开,这样反反复复,最终只剩下一个小孩子,求第几个小孩子留下? 提示:约瑟夫环即是一个首尾相连的链表,在建立好这个环以后,从头结点开始

超牛的Python,简单10行代码解决约瑟夫环

约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,直到圆桌周围的人全部出列.通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解. 虽然,用模拟去解决这个约瑟夫环问题效率是很低的,但是,这更容易理解.先上代码.    代码如下 复制代码 def josephus(n,k):      link=range(1,

【算法】1、约瑟夫环

  有n 个人围城一圈每次从1数起数到3就把那个人提出圈子,最后只保留一个人. 输入: 输入人数字符串输出:把最后一个人所保留位置返回出来.比如你输入11 的话即有11个人 [1,2,3,4,5,6,7,8,9,10,11] .返回的是7   解题:   package sj1; import java.util.ArrayList; import java.util.List; /** * * @author Administrator * 剔出某数字 */ public class sjt1

链表实现约瑟夫环

//Dev c++ #include<stdio.h>#include<malloc.h>#include<string.h>//调用putchar函数typedef struct stu{ int num; struct stu*next;}stu,*pointer;int main(){ int i,n,m,count; pointer p,q,r; r=p=q=(pointer)malloc(sizeof(pointer)); p->num=1;p->