约瑟夫环问题(数组和list方法)

先介绍一下什么是约瑟夫环问题:就是N个人围成一圈,从开头(下标为0)报数,报到你设置的Number就要出局,几轮下来后剩下最后一个人输出这个人的序号!

这里只介绍两种比较浅显易懂自己编写的代码,另外还有链表和递归的方式可以自行百度。生气

ok,第一种我们用数组来写。

int main()
{
	

	int total = 0;
	cout << "total:" << endl;
	cin >> total;
	int number = 0;
	cout << "number: " << endl;
	cin >> number;

	int *arr = new int[total];
	for (int i = 1; i <= total; i++)
	{
		arr[i - 1] = i;
	}
	int n = total;
	int shout = 1;
	int i = 0;
	while (total != 1)
	{
		if (arr[i] != -1)
		{
			i++;
			shout++;
		}
		else
		{
			i++;

		}
		if (i == 10)
		{
			i = 0;
		}
		if (shout == number && arr[i] != -1)
		{
			cout << arr[i] << "出局" << endl;
			arr[i] = -1;
			i++;
			shout = 1;
			total--;
		}


	}
	for (int i = 0; i < n; i++)
	{
		if (arr[i] != -1)
		{
			cout << "最后剩下" << arr[i] << endl;
		}
	}
	system("pause");

大概解释一下:代码前边比较好理解,给数组每个元素赋值,然后开始我们的循环,因为不知道要循环多少次所以我们用while循环,条件是什么呢?是总人数 >1,嗯。然后开始报数,我用了shout这个变量来记录当前报的数,如果报的数为number并且当前这个位置的人还在,我们就要把当前的值设为-1,代表当前位置的这个人没了,进行下次遍历,如果走到了最后一个,我们就要从头开始。结束后,我们再遍历一下数组,把值没被设置为-1的那个人输出。程序结束,附上vs2017下面的结果,还是蛮简单的对吧?大笑

ok,第二种,我们采用stl标准库当中list容器来写。


#pragma warning(disable:4996)
#include <iostream>
#include <list>
#include <stdio.h>
using namespace std;



int main()
{




	int total = 0;
	int number = 0;
	cout << "total :";
	cin >> total;
	cout << "number :";
	cin >> number;
	if (number < 1 || total < 1)
	{
		cout << "input error";
	}
	list<int>* table = new list<int>();
	for (int i = 1; i <= total; ++i)
	{
		table->push_back(i);
	}
	int shout = 1;
	list<int>::iterator it;
	for (it = table->begin(); table->size() != 1; )
	{
		if (shout++ == number)
		{
			cout << *it << "出局" << endl;
			it = table->erase(it);
			shout = 1;
		}
		else
		{
			it++;
		}
		if (it == table->end())
		{
			it = table->begin();
		}
	}
	cout << "The last one is:" << *table->begin() << endl;
	system("pause");

大致意思差不多,唯一的好处是list容器的大小是可以变化的,所以我们这边的判断条件是table->size() != 1;然后我们设置了一个迭代器去访问这个容器,如果发现当前位置的值等于number,我们就用erase()这个方法来删除这个位置,注意这边的用法,因为table->erase()返回的是一个地址。然后我们需要包含<list>头文件。没啦! 得意







  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值