约瑟夫环问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。编程思路:先建立一个循环链表,找到第一个报数的人,依次列出出列人的序号。#include <iostream>using namespace std;struct Node{ int id; Node *next; Node(int i) { id = i; next = NULL; }};struct LinkedList{ Node *head; int length; LinkedList(){ head = NULL; length = 0; }};/************************************************************************//* n 为总人数 *//* k 为第一个开始报数的人 *//* m 为出列者喊到的数 *//************************************************************************/void Josephus(int n, int k, int m){ if (n<0||k<0||m<0) { cout << "三个输入参数必须都为正整数" << endl; return; } if (n < k) { cout << "起始序号必须大于总人数" << endl; return; } //先建立循环链表 LinkedList *list = new LinkedList(); Node *node = list->head; Node *pnode = list->head; //先驱节点 for (int i = 1; i <= n; i++) { if (i == 1) { node = new Node(i); list->head = node; list->length++; node->next = node; } else { pnode = node; node = new Node(i); pnode->next = node; node->next = list->head; list->length++; } } //打印下,验证现有链表信息正确 Node *temp = list->head; for (int i = 1; i <= n; i++) { cout << temp->id << ends; temp = temp->next; } cout << endl; node = list->head; pnode = list->head; //找到第一个开始报数的人 while (--k) { pnode = node; node = node->next; } cout << "第一个开始报数的人的id:" << node->id << endl; int j = m - 1; cout << "出列人的id依次是:" << ends; while (n--) { for (j = m-1; j > 0; j--) { pnode = node; node = node->next; } cout << node->id << " " << ends; pnode->next = node->next; node = pnode->next; }}void main(){ Josephus(5, 3, 1); cout << endl; Josephus(5, 3, 2); cout << endl; Josephus(9, 2, 3);}
新闻热点
疑难解答
图片精选