题目描述
有n人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号的那位。
输入初始人数n
输出最后一人的初始编号
思路
我一开始想用链表解决这个问题,但是由于我还没开始复习数据结构,所以就搁置了。
但是这个题用数组依然可以解。链表的解决方式以后有时间再更。
- 初始化的时候数组的下标和对应的元素相等,如果直接删除数组元素可能会导致数组一些元素下标和对应的值不相等,所以对于需要删除的值,我选择将其值改为-1
- n个人围成一个圈,所以每排到一个人,他对应的下标就是之前的下标加一取模(n)
- 被排到的人有三种情况
1、下标对应的值不是-1即不是需要退出的值,且上一报数值加一取模(3),不为0,则现有的人数temp不需要变化(temp初始化为n)
2、下标对应的值不是-1即不是需要退出的值,且上一报数值加一取模(3),为0,则其下标对应的值更新为-1,现有的人数temp减一
3、下标对应的值是-1即是需要退出的值,则继续循环,temp不变
代码
#include <stdio.h>
#include <malloc.h>
int main()
{
int n, i, index, num, temp;
scanf("%d", &n);
int *a = (int *) malloc(n * sizeof(int));
for(i = 0; i < n; i++)
{
a[i] = i;
}
index = 0;
num = 0;
temp = n;
while(temp > 1)
{
index = (index + 1) % n;
if(a[index] != -1)
{
num = (num + 1) % 3;
if(num != 0)
{
continue;
}
else
{
a[index] = -1;
temp--;
}
}
else
{
continue;
}
}
for(i = 0; i < n; i++)
{
if(a[i] != -1)
printf("%d", i);
}
return(0);
}
小贴士
面对比较复杂的编程,先写出算法会更方便。