P1996 约瑟夫问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
n 个人围成一圈,从第一个人开始报数,数到 m 的人出列,再由下一个人重新从 1开始报数,数到 m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。
注意:本题和《深入浅出-基础篇》上例题的表述稍有不同。书上表述是给出淘汰 n−1 名小朋友,而该题是全部出圈。
输入两个整数 n,m。
输出一行 n 个整数,按顺序输出每个出圈人的编号。
输入
10 3
输出
3 6 9 2 7 1 8 5 10 4
1≤m,n≤100
//下面四篇博客和此题有一定联系。
约瑟夫环(分数10)_星河欲转。的博客-CSDN博客
约瑟夫环。_星河欲转。的博客-CSDN博客
猴子选大王_猴子选大王 go_星河欲转。的博客-CSDN博客
猴子选大王[加强版]_星河欲转。的博客-CSDN博客
//下面为大家提供六种解决办法,除第一种外,其他都参考自罗勇军《算法竞赛》一书。
//总的来说,此题考的是模拟,第一种方法比较简单易理解,其他的采用了链表知识,可以在草稿纸上推演一下过程就能更好的理解。
#include
using namespace std;
int main(){
int n,m,i,x=0,y=0;
mapa;//可以用数组,不过记得初始化。
cin>>n>>m;
while(y!=n){
for(i=1;i<=n;i++){
if(a[i]==0){
x++;
}
if(x==m){
x=0;
if(y)cout<<" ";
cout<
//动态链表
#include
using namespace std;
struct node{//定义链表节点
int data;//节点的值
node *next;//单向链表,只有一个next指针
};
int main(){
int n,m;
cin>>n>>m;
node *head,*p,*now,*prev;//定义变量
head=new node;head->data=1;head->next=NULL;//分配第1个节点,数据置为1
now=head;//当前指针是头
for(int i=2;i<=n;i++){
p=new node;p->data=i;p->next=NULL;//p是新节点
now->next=p;//把申请的新节点连到前面的链表上
now=p;//尾针后移一个
}
now->next=head;//尾指针指向头:循环链表建立完成
//以上是建立链表,下面是此题的逻辑和流程,后面4种代码与下面的逻辑流程完全一致。
now=head,prev=head;//从第1个开始数
while((n--)>1){
for(int i=1;inext;
}
printf("%d ",now->data);//输出第m个节点
prev->next=now->next;//跳过这个节点
delete now;//释放这个节点
now=prev->next;//新的一轮
}
printf("%d",now->data);//打印最后一个节点
delete now;//释放最后一个节点
return 0;
}
//用结构体数组实现单向静态链表
#include
using namespace std;
const int N=105;//定义静态链表的空间大小
struct node{//单向链表
int id,nextid;//单向指针
//int data;//如有必要,定义一个有意义的数据
}nodes[N];//定义在全局的静态分配
int main(){
int n,m;
cin>>n>>m;
nodes[0].nextid=1;
for(int i=1;i<=n;i++){
nodes[i].id=i;nodes[i].nextid=i+1;
}
nodes[n].nextid=1;//循环链表:尾针向头
int now=1,prev=1;//从第1个节点开始
while((n--)>1){
for(int i=1;i
//用结构体数组实现双向静态链表
#include
using namespace std;
const int N=105;
struct node{//双向链表
int id;//节点编号
//int data;
int preid,nextid;//前后节点
}nodes[N];
int main(){
int n,m;
cin>>n>>m;
nodes[0].nextid=1;
for(int i=1;i<=n;i++){//建立链表
nodes[i].id=i;
nodes[i].preid=i-1;//前节点
nodes[i].nextid=i+1; //后节点
}
nodes[n].nextid=1;//循环链表:尾针向头
nodes[1].preid=n;//循环链表:头指向尾
int now=1;//从第1个节点开始
while((n--)>1){
for(int i=1;i
//用一维数组实现单向静态链表
#include
using namespace std;
int nodes[150];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n-1;i++)nodes[i]=i+1;//下一个节点
nodes[n]=1;//循环链表:尾指向头
int now=1,prev=1;//从第1个节点开始
while((n--)>1){
for(int i=1;i
//STL list
#include
using namespace std;
int main(){
int n,m;
cin>>n>>m;
listnode;
for(int i=1;i<=n;i++)node.push_back(i);//建立链表
list::iterator it=node.begin();
while((n--)>1){//list的大小由STL自己管理
for(int i=1;i::iterator next=++it;
if(next==node.end())next=node.begin();//循环链表
node.erase(--it);//删除这个节点,node.size()自动减1
it=next;
}
cout<<*it;
return 0;
}