牛刀小试 - 约瑟夫生者死者小游戏

/*********************************************************************
程序名: 约瑟夫生者死者小游戏
说明:30 个人在一条船上,超载,需要 15 人下船。
于是人们排成一队,排队的位置即为他们的编号。
报数,从 1 开始,数到 9 的人下船。
如此循环,直到船上仅剩 15 人为止,问都有哪些编号的人下船了呢?

1. 使用数组
2. 使用链表
3. 公式法递推
*********************************************************************/
#include   
#include   
using namespace std;


#define LIVES 30	// 船上的初始人数
#define DEADS 15	// 需要下船的人数
#define DEAD_NUM 9	// 数到该数下船

void SolutionByArray()
{
	static int died[LIVES];  // 0代表在船上,1代表下船了(默认全是0)
	int i, j, cur = 0;		 // cur表示当前报数的人的编号-1
	for (i = 0; i < DEADS; i++)		// 每次循环下船一个人
	{
		for (j = 0; j < DEAD_NUM; j += 1 - died[cur++])  // 当died[cur] = 0 时,j++ ,当died[cur] = 1 时,j = j
		{
			if (cur == LIVES)		// 最后一个人报完则又从第一个人开始
				cur = 0;
		}
		cout << "第" << cur << "号下船了" << endl;
		died[cur - 1] = 1;  // 记录下船信息
	}
}

struct person
{
	unsigned id;
	struct person *next;
}persons[LIVES], *p, *before;

void SolutionByLinkedList()
{
	int i, j;
	// 初始化循环链表
	for (i = 0; i < LIVES; i++)
	{
		persons[i].id = i + 1;// 从1开始给船上的人编号
		persons[i].next = persons + i + 1;
	}
	persons[LIVES - 1].next = persons;
	p = persons + LIVES - 1;  // 计数开始时会忽略第一个人,故设置初始值为最后一个人
	for (i = 0; i < DEADS; i++){
		for (j = 0; j < DEAD_NUM - 1; j++)
		{
			p = p->next;
		}
		// 使before指向下船人的前一个人
		before = p, p = p->next;
		cout << "第" << p->id << "号下船了" << endl;
		before->next = p->next;
	}
}

void SolutionByRecursion()
{
	int i, j, id;// id表示下船的人的编号
	for (i = 0; i < DEADS; i++){// 每次循环下船一个人
		for (j = i, id = -1; j >= 0; j--){
			id = (id + DEAD_NUM) % (LIVES - j);
		}
		cout << "第" << id + 1 << "号下船了" << endl;
	}
}

int main()
{
	SolutionByRecursion();

	system("PAUSE");
	return 0;
}

你可能感兴趣的:(C++学习,c++)