约瑟夫环【队列】

约瑟夫环的队列解法

  • 1,了解C++中的队列
  • 2,题目
  • 3,演示
  • 4,代码

1,了解C++中的队列


	queue<int> Q; //创建一个int类型的队列,队列名为Q
	
	Q.push()			//进队列(在队尾插入新元素) 
	Q.pop()				//出队列
	Q.empty()			//判断队空 
	Q.front()			//取队头元素(不删除队头元素)
	Q.back()			//返回队尾元素的值(不删除该元素)
	Q.size()			//返回队列中元素的个数 (这道题用不到)

2,题目

Problem 1206 约瑟夫环………………数构
Accepted: 898 Total Submit: 1564
Time Limit: 1000ms Memony Limit: 32768KB
Description
约瑟夫问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个整数作为报数上限值,从第一个人开始顺时针自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他顺时针方向上的下一个人开始重新从1报数。如此下去,直至所有的人全部出列为止。试设计一个程序,求出出列顺序。
Input
先输入一个正整数T,表示有T组测试案例。每组测试案例的第一行是两个整数n、m,分别表示有n个人和一开始的上限值。第二行有n个正整数被空格隔开,表示每人持的密码。
Ouput
对每一组测试案例,先输出一行“Case id:”,id从1开始。然后按照出列顺序输出各人的编号,输出格式见样例。
Sample Input
1
5 2
1 3 4 3 2
Sample Output
Case 1:2->5->3->1->4

3,演示

1,刚开始有五个人,所以创建一个五个人的队列
约瑟夫环【队列】_第1张图片
2,第一步,第二个人出列
让1往后站
约瑟夫环【队列】_第2张图片
这时候该2往后站
可是2要出列;
所以要删除2;
约瑟夫环【队列】_第3张图片
3,2的密码是三,所以现在要让第三个人(也就是5)出列
过程应该是这样的:
约瑟夫环【队列】_第4张图片
约瑟夫环【队列】_第5张图片
约瑟夫环【队列】_第6张图片
3,5的密码是二,所以现在要让第二个人(也就是3)出列
过程:
约瑟夫环【队列】_第7张图片
约瑟夫环【队列】_第8张图片
3,3的密码是四,所以现在要让第四个人(也就是1)出列
过程:
约瑟夫环【队列】_第9张图片约瑟夫环【队列】_第10张图片
在这里插入图片描述
约瑟夫环【队列】_第11张图片
最后只剩下一个4了;

4,代码

#include
#include
struct st
{
	int num;
	int password;
};
using namespace std;
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int m,n;
		cin>>m>>n;
		queue<st> Q;//创建一个st类型的队列 
		st t;
		for(int i=1;i<=m;i++)
		{
			
			int password;
			cin>>password;
			
			t.num=i;
			t.password=password;
			
			Q.push(t);
		}
		int cut=0;
		while(Q.size()!=1)   	//直到队列里剩下1个人的时候停止
		{
			cut++;				//用cut=密码的时候,那个人就要离队了
			if(cut!=n)
			{
				t=Q.front();  
				Q.pop();		//删除队头
				Q.push(t);		//把刚才的队头放到队尾
			}
			else
			{
				n=Q.front().password;	//把出队的人密码记下来
				Q.pop();				//然后删掉他
				cut=0; 
			}
		}
		cout<<Q.front().num;
	} 
} 

你可能感兴趣的:(其他题目,c++)