题目描述
n 个人围成一圈,从第一个人开始报数,数到 m的人出列,再由下一个人重新从 1 开始报数,数到 m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。
输入格式
输入两个整数 n,m。
输出格式
输出一行 n 个整数,按顺序输出每个出圈人的编号。
搜是搜的队列数据结构,出来这么一道题,随意在中间拿掉元素,看起来不像是队列能做的,队列是先进先出表,不知道有什么联系,反而是循环链表更容易频繁的拿掉中间的值,网上搜了循环链表的轮子,不知为何用不了。后来气急败坏,便用了顺序表。采用了递归的算法,代码如下
#include <stdio.h>
int array[1000];
int num=0;
typedef struct
{
int a[1000];
int max;
}list;
deletelist(list* l,int location)
{
int i,j,k;
int t[1000];
if(location > l->max)
{
j=location - l->max;
deletelist(l,j);
}
if(location <= l->max)
{
array[num] = l->a[location];
num++;
for(i=location;i < l->max;i++)
{
l->a[i]=l->a[i+1];
}
l->max=l->max-1;
//删除后重新排序
for(i=1;i<=l->max;i++)
{
t[i]=l->a[i];
//printf("%d",t[i]); //先存起来
}
//printf("*\n");
k=1;
for(i=location;i <= l->max;i++)
{
l->a[k]=t[i];
// printf("%d ",l->a[k]);
k++;
}
// printf("\n");
for(i=1;i<=location-1;i++)
{
l->a[k]=t[i];
k++;
}
}
}
int main()
{
int m,n,i;
list la;
scanf("%d %d",&n,&m);
la.max = n;
for(i=1;i<=la.max;i++)
{
la.a[i]=i;
//printf("%d",la.a[i]);
//printf("\n");
}
for(i=1;i<=n;i++)
{
deletelist(&la,m);
}
for(i=0;i<num;i++)
{
printf("%d ",array[i]);
}
return 0;
}
思路如下:
定义一个全局变量,将序号上面的元素赋值给全局变量,之后删掉这个点,再对其重新排序。
如果遇到要删的序号比剩下的人多怎么办。这就体现了我递归的思想了。
if(location > l->max)
{
j=location - l->max;
deletelist(l,j);
}
那就删除位置减去最大人数的位置的人,意味着走到头了重新开始,如果还不行那就再递归。
做完之后就AC了。
然后查看别人的题解
然后意识到一个严峻的问题:
我是废物