洛谷-P1996 约瑟夫问题
圈-队列
刚开始被队列只能取队头队尾元素而迷惑,其实可以把用不到(不是第m个数)放队尾
法一:队列
不得不说,巧妙使用数据结构,真的很nice~
这个时候就不用考虑数字越界的问题了!!
#include<bits/stdc++.h>
using namespace std;
int main(){
queue<int> q;
int n,m;
cin>>n>>m;
//将数字放入队列里
for(int i=1;i<=n;i++){
q.push(i);
}
while(!q.empty()){
for(int i=1;i<m;i++){
// 未走到第m个数时,把该数放队尾
int temp=q.front();
q.pop();
q.push(temp);
}
// 输出第m个数,也就是队头
cout<<q.front()<<" ";
q.pop();
}
}
法二:模拟数组
好像数组也不难 是我想的太复杂
起初只想到每次走m-1步,很麻烦,还要考虑取余...合适的办法是每次走一步
而且下一个位置一定是0位置,为1代表该数已经出去了,利用while循环来判断
PS:数组一定记得初始化,系统不会默认赋0值
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;
int count=0;
int pos=0;
cin>>n>>m;
int mark[105]={0};
//利用出去的个数来判断是否全都出去,而不是通过for循环去遍历数组,去检验数组的每个值为1
while(count!=n){
// 每次移动一步,就不用考虑取余
for(int i=1;i<=m;i++){
pos=(pos+1>n?1:pos+1);
//下一个位置应该是mark值为0的地方,因为1代表已经出去
while(mark[pos]) pos=(pos+1>n?1:pos+1);
}
cout<<pos<<" ";
mark[pos]=1;
count++;
}
}

浙公网安备 33010602011771号