1->数组解法
#include<cstdio>
#include<iostream>
using namespace std;
bool a[110];//a[x]表示x这个编号是否出局
int cnt,i,k;//cnt计数目前已经出局的人数,k表示已经报数的人数
int n,m;
int main()
{
cin>>n>>m;//总共有n人,数到数字m时出局
while(cnt!=n)//全部出局,程序结束
{
i++;//向右走
if(i>n) i=1;//循环报数,n+1-->1
if(a[i]==0)//如果i没有出局
{
k++;
if(k==m)
{
cout<<i-1<<' ';//人从0开始编号
a[i]=1;//出局
k=0;//清空k,重新从1开始报数
cnt++;
}
}
}
return 0;
}
2->循环链表解法
#include<cstdlib>
#include<iostream>
using namespace std;
typedef struct node
{
int data;
struct node *next;
}Node;//重命名
void ysflb(int n,int k)
{
Node *head=NULL,*p=NULL,*r=NULL;//定义指针赋初值,如果没有申请空间则赋值为NULL
head=(Node *)malloc(sizeof(Node));//链表的第一个元素,即头结点
if(head==NULL)//申请失败
{
cout<<"Memory Failed";
return ;
}
head->data=0;//编号为0
head->next=NULL;
p=head;//head不能动,用p代替
//尾插法创建链表
for(int i=1;i<n;i++)//缺n-1个结点,用for循环插入
{
r=(Node *)malloc(sizeof(Node));//申请一个结点
r->data=i;
r->next=NULL;
p->next=r;//由p连接r
p=r;//p向后走一步,方便下一个结点进入
}
p->next=head;//循环链表->尾巴连向头
p=head;//方便while循环
while(p->next!=p)//只有p一个结点
{
for(int i=1;i<k;i++)//报数
{
r=p;//r存p的前一个元素
p=p->next;//p
}
cout<<p->data<<" ";
r->next=p->next;//删除p结点
p=p->next;//重新循环报数
}
cout<<p->data;//推出while时,剩余最后一个结点,输出
}
int main()
{
int a,b;
cin>>a>>b;
ysflb(a,b);
return 0;
}
3->递归解法
i!=1 ysf(n,k,i)=(ysf(n-1,k,i-1)+k)%n
i==1 ysf(n,k,i)=(k-1+n)%n 加n取模结果相同,防负数
// i!=1 ysf(n,k,i)=(ysf(n-1,k,i-1)+k)%n
// i==1 ysf(n,k,i)=(k-1+n)%n
#include<iostream>
using namespace std;
int ysf(int n,int k,int i)//总共有n个人,第i个报数为k的人出局
{
if(i==1) return (k-1+n)%n;//第一个: 没有超过人数范围->k-1 超过范围-> (k-1)%n
return (ysf(n-1,k,i-1)+k)%n;//第二次所走的编号+第一次的循环周期
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cout<<i<<' '<<ysf(n,m,i)<<endl;
return 0;
}