问题描述
有编号问1~n个人按顺时针方向围坐一圈,每个人都持有一个密码(正整数)。一开始任选一个数m,从编号为1的人开始按顺序报数,数到m时停止报数,数到m的人出列,并将他的密码作为新的m值继续报数,直到所有人都出列为止。
思路分析
假设给定一组n=7个人分别持有的密码3,1,7,2,4,8,4.m初始值为6.从第一个人开始,数到6,8出列,并且m=8,继续从下一个人从1开始报数,数到8(此时密码为8的人已出列,故无需再报数)的人出列,将其密码替换m值…直到所有人出列为止。
很显然这是一道模拟题,我们只需要模拟报数,出列的过程即可,可想到利用循环链表实现或数组实现
实现过程
#include<bits/stdc++.h>
using namespace std;
struct node
{
int num; //定义编号
int del; //定义密码
node *next; //定义一个指向下一结构体的指针
};
int main()
{
int n,m;
node *p,*q,*first; //定义指向结构体的指针
cin>>n>>m;
for(int i=1;i<=n;i++)
{
if(i==1)
{
first=p=(node*)malloc(sizeof(node));
if(p==0)
return 0;
}
else
{
q=(node*)malloc(sizeof(node));
if(q==0)
return 0;
p->next=q;
p=q;
}
cin>>(p->del);
p->num=i;
}
p->next=first; //尾部指针指向第一个结构体,连接构成循环链表
p=first;
for(int i=1;i<=n;i++)
{
for(int j=1;j<m;j++) //模拟报数过程
p=p->next;
m=p->del; //报到m的人出列,将其密码赋值为新的m值
cout<<p->num<<" "; //打印出列人的编号
p->num=p->next->num; //模拟出列过程
p->del=p->next->del;
q=p->next;
p->next=p->next->next;
free(q);
}
cout<<endl;
return 0;
}
数组实现:这里只用到了一个数组,如出列删除数组中的元素则涉及到移位,会增加代码的复杂程度,这里通过数组下标也可达到相同效果。
#include<bits/stdc++.h>
using namespace std;
int a[35];
int main()
{
memset(a,0,sizeof(a));
int n,m;
cin>>n>>m;
for(int i=0; i<n; i++)
cin>>a[i];
int cnt=1,j=-1; //cnt为出列次数,j控制数组下标
while(cnt<=n)
{
int i=0; //控制报数次数
while(1)
{
j=(j+1)%n;
if(a[j]>=0)
i++;
if(i==m)
{
cnt==n?cout<<j+1<<endl:cout<<j+1<<" ";
m=a[j];
a[j]=-1; //通过改变出列值为负数模拟出列过程
cnt++;
break;
}
}
}
return 0;
}
小编有话说
本人还是一个资历尚浅正在学习编程的小白,如发现本文有何不妥之处,欢迎各位留言指出,我一定虚心接受。
转载:https://blog.csdn.net/q614701220/article/details/102411787
查看评论