习题3.10 约瑟夫环 josephus问题

/* assume a header */
/* 双向循环链表 */
struct Node;
typedef struct Node * PtrToNode;
typedef PtrToNode List;
typedef PtrToNode position;

struct Node{
    PtrToNode Previous;
    PtrToNode Next;
    int Ele;
};
/* 删除双向循环链表中的元素例程 */
Position
Delete( Position p )
{
    Position tmp;
    tmp = p->next;
    p->Previous->Next = tmp;
    tmp->Previous = p->Previous;
    free( p );
    return tmp;
}
void
josephus( List L, int m, int n )
{
    int i,count = 0;
    Position p;
    p = L->Next;
    while( n > 1 )
    {
        count = m % n;
        for(i = 0; i < count; i++)
            p = p->Next;
        p = Delete( p );
        n--;
    }
    printf("%d",p->Ele);
}

L默认为双向循环链表,L为表头,Delete为删除双向链表结点的函数

整个表结构类似一个圆圈上面加一个表头

拓展:创建一个双向循环链表,以输入为0结束

struct Node{
    PtrToNode Previous;
    PtrToNode Next;
    int Ele;
};
//创建一个双向循环链表
Position
CreateDoubleList( void )
{
   PtrToNode head,last,now;
   head = last = malloc( sizeof(struct Node ) );
   now = malloc( sizeof(strut Node ) );
   scanf("%d",&now->Ele);
   while(now->Ele != 0)
   {
       last->Next = now;
       now->Previous = last;
       last = now;
       now = malloc( sizeof( struct Node ) );
       scanf("%d",&now->Ele);
   }
   last->Next = head;
   head->Previous = last;
   free(now);
   return head;
}

创建一个单链表,类似

//创建一个单向链表

struct Node{
    int data;
    PtrToNode Next;
};
Position
CreateSingleList( void )
{
    Position head,last,now;
    head = last = malloc( sizeof( struct Node ) );
    now = malloc( sizeof( struct Node ) );
    scanf("%d",&now->data);
    while(now->data != 0)
    {
        last->Next = now;
        last = now;
        now = malloc( sizeof( struct Node ) );
        scanf("%d",&now->data);
    }
    last->Next = NULL;
    free(now);
    return head;
}

时间: 2024-08-27 15:37:55

习题3.10 约瑟夫环 josephus问题的相关文章

华为历年试题(10约瑟夫环)

约瑟夫环形问题 有30人将其编号,从头开始1,2,3数数,每到3将其删除,一共删去15个数.输出被删去的15个数 #include<iostream> using namespace std; struct LinkList { int val; LinkList* next; LinkList(int a):val(a),next(NULL){} }; LinkList *CreatList(int n) { LinkList *p = new LinkList(1); LinkList *

约瑟夫环问题(Josephus)

[问题描述] 用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出.写出C程序.(约瑟夫环问题 Josephus) [解题思路] 构建一个循环链表,每个结点的编号为1,2,......,n.每次从当前位置向前移动m-1步,然后删除这个结点. [C程序代码] #include <stdio.h> #include <stdlib.h> typedef struct node { int num; struct node *next; }node; node *

组合数学--约瑟夫环问题 Josephus

约瑟夫斯问题(有时也称为约瑟夫斯置换),是一个出现在计算机科学和数学中的问题.在计算机编程的算法中,类似问题又称为约瑟夫环. 有n个囚犯站成一个圆圈,准备处决.首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人. 接着,再越过k-1个人,并杀掉第k个人.这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着. 问题是,给定了n和k,一开始要站在什么地方才能避免被处决? 问题是以弗拉维奥·约瑟夫斯命名的,它是1世纪的一名犹太历史学家.他在自己的日记中写道,

Josephus环的四种解法(约瑟夫环)

约瑟夫环 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列.通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解引用别人的一个图:直观说明问题 分析: 第一步:从1开始报数为3的时候就删除3号结点第二步:从4号结点开始报数,当为3的时候删除6号结点:第三步:从7号结点开始报数,当为3的时候

HDU 3089 (快速约瑟夫环)

Josephus again Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 652    Accepted Submission(s): 181 Problem Description In our Jesephus game, we start with n people numbered 1 to n around a circle

用循环链表解决约瑟夫环问题

约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,直到圆桌周围的人全部出列. 下面我们用循环列表模拟这个过程: 1 //节点定义与单链表相同,在此省略 2 //use cyclical linked list to solve josephus problem 3 template <typename Type> class Linked

1139 约瑟夫环问题

1139 约瑟夫环问题 时间限制:500MS  内存限制:65536K提交次数:157 通过次数:79 题型: 编程题   语言: G++;GCC Description 约瑟夫(josephus)环是这样的:假设有n个小孩围坐成一个圆圈,并从1开始依次给每个小孩编上号码.老师指定从第s位小孩起从1开始报数,当数到m时,对应的小孩出列,依次重复,问最后留下的小孩是第几个小孩?例如:总共有6个小孩,围成一圈,从第一个小孩开始,每次数2个小孩,则游戏情况如下: 小孩序号:1,2,3,4,5,6 离开

C++ 用循环链表解决约瑟夫环问题

约瑟夫环问题 已知 n 个人(n>=1)围坐一圆桌周围,从 1 开始顺序编号,从序号为 1 的人开始报数,顺时针数到 m 的那个人出列.下一个人又从 1 开始报数,数到m 的那个人又出列.依此规则重复下去,直到所有人全部出列.请问最后一个出列的人的初始编号. 要求 输入人数 n,所报数 m,输出最后一个人的初始编号. 解决思路 首先因为是圆桌问题,使用链表解决的话需要构建循环链表. 接着是出列问题,这里我的设计思路是将指向链表的指针移动到需要出列的人的位置,然后根据正常的链表删除进行操作即可.

约瑟夫环问题的两种实现[链表+数组]

约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,直到圆桌周围的人全部出列. 以下是使用循环链表和数组的两种实现: 1 #include<iostream> 2 using namespace std; 3 4 struct Node 5 { 6 int data; 7 Node *next; 8 }; 9 void CreateLink