约瑟夫问题
来源:互联网 发布:冷钢刀怎么样啊 知乎 编辑:程序博客网 时间:2024/06/12 01:24
约瑟夫问题是经典的循环链表。
1)内容: 约瑟夫(Joseph)问题的一种描述是:编号为1,2,…, n 的n 个人按顺 时针方向围坐一圈, 每人持有一个密码(正整数)。一开始选任一个正整数作为报数上限值m, 从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将它的密码作为新的m值,再从下个人开始新一轮报数,如此反复,直到剩下最后一人则为获胜者。试设计一个程序求出出列顺序。
2)要求: 利用单向循环链表存储结构模拟此过程, 按照出列的顺序印出各人的编号。
3) 测试数据: n=7,7 个人的密码依次为:3,1,7,2,4,8,4 。m的初值为20,则正确的出列顺序应为6,1,4,7,2,3,5
#include <stdio.h>#include <stdlib.h>// 结构体的定义typedef struct Person { int order; int password; struct Person * next;} Person;Person * pHead = NULL; // 链表的第一个节点 Person * pTail = NULL; // 链表的尾部 Person * per = NULL; // 用于遍历 int n, m;// 下面是函数的声明void Create(); // 创建一个链表void Joseph(int m); // 约瑟夫问题的执行函数int main(void){ // n为总人数, m为初始密码 scanf("%d %d", &n, &m); Create(); // 创建链表 per = pHead; // 将用于遍历的节点指向头节点,因为下面的这个函数使用递归写的 Joseph(n); return 0;} void Create() { // 定义一个为节点 Person * tail; for (int i = 0; i < n; i++) { Person * person; person = (Person *) malloc(sizeof(Person)); person->order = i + 1; scanf("%d", &person->password); if (pHead == NULL) { pHead = person; } else { tail->next = person; } tail = person; } // 因为是循环链表,所以必须将尾与头连接起来 tail->next = pHead; // 将函数中的尾节点赋给全局变量中的尾节点 // 这个在后面有用 pTail = tail;}/** 因为最后最后每一个人都会报数(最后一个报数的为获胜者)* 一次递归出列一个人,所以要需要递归n次*/void Joseph(int number) { // 当number为0时结束递归 if (number == 0) { return; } // 用于报数,第一个人报1所以初始值为1 int count = 1; // p用于记录删除的节点 Person * p = NULL; // 前面记录的为指针的用处就在这里 // 当m=1时,第一个人出列,所以就不用进行下面的循环 // 但是当m不等于1时,找到那个要出列的节点 while (count != m) { per = per->next; pTail = pTail->next; count++; } // p为要删除的节点 p = per; // 重置m m = p->password; // 从链表中删除p pTail->next = per->next; // 下面的是输出出列人的编号 // 因为有些ACM要求,用空格间隔,所以最后一个不能有空格 if(number == 1) printf("%d", p->order); else printf("%d ", p->order); per = per->next; // 释放p free(p); // 进行下一个递归 Joseph(number - 1); }
约瑟夫排列问题
对于给定的1,2,3,…,n中的k个数,Josephus想知道是否存在一个正整数m(m≤n),使得Josephus(n,m)排列的最后k个数恰好为事先指定的k个数。例如当n为7,k为4,指定排列的最后k个数为7,5,1,4时;由于(7,3)Josephus排列为3,6,2,7,5,1,4;所以求得m值为3。
这个约瑟夫排列问题,每个人都没有密码,只有一个初始值,当报到这个人时出列。要求找一个满足题目要求的初始值m。
#include <stdio.h>#include <stdlib.h>typedef struct Person { int order; struct Person * next;} Person;Person * pHead = NULL; // 链表的第一个节点 Person * pFront = NULL;Person * per = NULL;int n, m;int b[100], k;// 函数void Create(); void Joseph(int number, int m);int main(void){ scanf("%d %d", &n, &m); int i; int a[n]; for (i = n - m ; i < n; i++) { scanf("%d", &a[i]); } for (i = 1; i <= n; i++) { pHead = NULL; pFront = NULL; k = 0; int flag = 1; Create(); per = pHead; Joseph(n, i); for (int j = n - m; j < n; j++) { if (a[j] != b[j]) { flag = 0; } } if (flag == 1) { printf("%d", i); return 0; }// printf("\n"); } printf("0"); return 0;} void Create() { Person * tail; for (int i = 0; i < n; i++) { Person * person; person = (Person *) malloc(sizeof(Person)); person->order = i + 1; if (pHead == NULL) { pHead = person; } else { tail->next = person; } tail = person; } tail->next = pHead; pFront = tail;}void Joseph(int number, int m) { if (number == 0) { return; } int count = 1; Person * p = NULL; while (count != m) { per = per->next; pFront = pFront->next; count++; } p = per; pFront->next = per->next; if(number == 1) { b[k++] = p->order;// printf("%d", p->order); } else {// printf("%d ", p->order); b[k++] = p->order; } per = per->next; free(p); Joseph(number - 1, m); }
0 0
- 约瑟夫问题、约瑟夫环
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 约瑟夫问题
- 在自己的linux服务器上面部署ShowDoc
- 人见人爱A^B之解题思路
- php面试题
- 既使用maven编译,又使用lib下的Jar包
- ZOJ 2319 (二维的LIS)
- 约瑟夫问题
- 任务管理RHCE-Day5
- 【深入Java虚拟机】之三:类初始化
- C/C++读写BMP文件
- L2-020. 功夫传人
- CodeIgniter首页或尾页没有出现的原因
- 扫描某个包下所有的类,输出所有使用了特定注解的类的注解值
- 解决Dynamic Web Module 3.1 requires Java 1.7 or newer
- HTML5第一个项目:HelloWorld!