每日一题14:数组与链表组合方案下的Josephus问题
来源:互联网 发布:学java工程师 编辑:程序博客网 时间:2024/06/03 23:04
愚人节快乐!几天没写程序,今天继续!Josephus问题是说N个人围成一个圈传热土豆,先约定一个数M,当传递了M次的时候拿着土豆的人出局,然后将土豆给出局人的下一个人,游戏继续,直到最后只剩下一个人,求出局人的序列(按出局顺序排列)。
这个问题可以用数组实现,但是需要标记代表出局人的元素,并且没遍历一个元素就要检查该元素是否已被标记为出局,这样程序运行时间必然会变慢。另一种方式是使用一个链表,每次把出局的节点删除掉。这样的解决方案非常直观,只需要关注链表中的节点,因为在链表中的节点就是没有出局的。删除节点只是指针的调整,非常迅速,但是释放删除的节点占用的空间会比较费时,当输入N很大时会占用大量的时间。所以采用一种链表与数组结合的方式,可以克服两种方式的缺点。
结合的方式就是把链表放在一个数组中!初始时,每个元素的next指针指向数组的下一个元素,最后一个指向第一个(我们需要的是一个循环链表)。这样我们就可以实现在数组中跳跃性的访问而不必关心访问的节点是否是被标记为出局,最后只要一次性释放掉数组所占用的空间就好了,不用管链表节点的释放!
#include "stdafx.h"#include <iostream>using namespace std;struct person{ int id; person* next;};struct person_list{ int count; person* first; person* last;};person_list* init(int n){ person* p = new person[n]; for (int i = 0; i < n - 1; ++i) { p[i].id = i + 1; p[i].next = &p[i+1]; } p[n - 1].id = n; p[n - 1].next = &p[0]; person_list* persons = new person_list; persons->count = n; persons->first = p; persons->last = &p[n - 1]; return persons;}int* solve(int n,int m){ if(n < 1 || m < 0) return NULL; person_list* persons = init(n); person* first = persons->first; person* t = first; int count = persons->count; int *losers = new int[n]; int j = 0; while(count > 1) { person* q = NULL; for (int i = 0; i < m; ++i) { q = first; first = first->next; } if(first == persons->first) { persons->first = first->next; persons->last = persons->first; } else if(first == persons->last) { q->next = first->next; persons->last = q; } else { q->next = first->next; } --count; losers[j++] = first->id; first = first->next; } losers[j] = persons->first->id; delete []t; delete persons; return losers;}int _tmain(int argc, _TCHAR* argv[]){ int n = 5, m = 1; int* losers = solve(n,m); for (int i = 0; i < n; ++i) { cout<<losers[i]<<' '; } cout<<endl; delete[]losers; return 0;}
程序中losers数组的最后一个元素保存的是最后胜利的人,之前才是出局人序列。
生活中许多事情也像写程序,哪里不会出点bug呢,但是bug总会被修复的不是吗?
0 0
- 每日一题14:数组与链表组合方案下的Josephus问题
- josephus 问题的数组解法
- 每日一题(63) - 排列与组合
- 利用数组模拟的链表解决Josephus问题
- Josephus问题的链表实现
- 链表形式的josephus问题
- 每日一道算法题:打印一维数组的所有组合
- Josephus问题(基于数组的实现)
- 从面向结构到面向对象-----josephus问题(方法一:数组的应用)
- 链表应用:Josephus问题
- Josephus问题 循环链表
- 链表相交问题【每日一题】
- Josephus问题(约瑟夫问题)链表的实现
- Josephus问题的一种解法(链表实现)
- josephus问题->不带头节点的循环链表
- 用数组求解Josephus问题
- 每日一题(41)—— 数组和链表的区别
- 【每日一题-1】有序链表合并与累加和问题
- 分享复制文件,并将文件扩展名更改为.txt
- 新浪微博(第二天)
- WhitespaceAnalyzer方法的使用
- uva 10401 受伤的皇后dp
- WebView学习笔记
- 每日一题14:数组与链表组合方案下的Josephus问题
- FFmpeg命令行工具系列二---转码流程及过滤器
- Java基础第十七天--IO流1
- PHP使用curl替代file_get_contents
- iOS 开发的9个超有用小技巧
- C++强制类型转换
- Tizen中的HTML5资源加密措施
- HDOJ 3068 最长回文
- thinking in Java --01对象导论