约瑟夫环的队列解法
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,刚开始有五个人,所以创建一个五个人的队列
2,第一步,第二个人出列
让1往后站
这时候该2往后站
可是2要出列;
所以要删除2;
3,2的密码是三,所以现在要让第三个人(也就是5)出列
过程应该是这样的:
3,5的密码是二,所以现在要让第二个人(也就是3)出列
过程:
3,3的密码是四,所以现在要让第四个人(也就是1)出列
过程:
最后只剩下一个4了;
4,代码
#include<iostream>
#include<queue>
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;
}
}