约瑟夫问题(寻找猴王)

Joseph问题

  • 思路
  • 函数与类
  • 具体代码

题目内容:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。

输入格式:输入包含两个整数,第一个是n,第二个是m (0 < m,n <=300)。

输出格式:输出包含一行,即最后猴王的编号。

输入样例:18 2

输出样例:5


思路

  1. 使用一个循环链表将这些猴子串起来,每次报号后就向后 ☞ work = work->next ; 当报号到所输入的num时候便删除当前节点。
  2. 使用双向循环链表,使删除操作更简单。
  3. 注意我使用work指向的下一个节点,即:若我设置编号为 1–2--3–4--5–6 的序列设置口号 2 则 报完第一个轮次后,work节点为 3,设立一个temp节点为 2,然后delete temp ; 从而使work节点始终处于工作状态直至 work->next = work(只有一个节点)即为King。

函数与类

/* Author : YaaaZa!   
*  Time	  : 2018.10.20
*  Joseph_Qus
*/
struct Node {   				//节点结构体
	int data;
	Node* next;
	Node* prev;
};

class list   					//链表类
{
	Node* head;
	Node* tail;
public:
	list() { head = NULL; }
	bool Init(int num);			//链表创立
	int getKing( int n);		//求解函数
};

具体代码

/* Author : YaaaZa! 
*  Time	  : 2018.10.20
*  Joseph_Qus
*/
#include "stdafx.h"
#include
using namespace std;
struct Node {
	int data;
	Node* next;
	Node* prev;
};

class list
{
	Node* head;
	Node* tail;
public:
	list() { head = NULL; }
	bool Init(int num);//链表
	int getKing( int n);
};
bool list::Init(int num) {
	Node* p;
	p = new Node;
	head = p;
	tail = p;
	int a = 1;	
	head->data = a++;
	head->next = NULL;
	head->prev = NULL;
	for (; a <= num; a++) { //输入序号 -1 结束
		p = new Node;
		p->data = a;
		tail->next = p;
		p->prev = tail;
		tail = p;
		tail->next = NULL;
	}
	tail->next = head;
	head->prev = tail;
	return true;
}
int list::getKing(int n) {
	Node *temp,* work;
	work = head;
	while(work->next != work) {
		for (int i = 1; i < n; i++) work = work->next;
		temp = work;
		work = work->next;
		temp->prev->next = temp->next;
		temp->next->prev = temp->prev;
		delete temp;
	}
	return work->data;
}
int main()
{
	int king = -1;
	int num = -1;
	int monkynum = 0;
	list group;
	cin >> monkynum;
	group.Init(monkynum);
	cin >> num;
	king = group.getKing(num);
	cout<

你可能感兴趣的:(Data,Structures,题目)