洛谷-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++;
}
}
posted @ 2025-03-18 16:31  夕瑶^  阅读(57)  评论(0)    收藏  举报