约瑟夫环
题目:有n个人围成一圈,顺序排号,从第一个开始报数(从1到3报数),凡报到3的人退出圈子,问最后最后留下的是原来第几号的那位.
提示:用数组完成
提示:用数组完成
结题思路:
1)先对n个元素初始化,内容与编号相同;
2)定义两个数组,一个用于存放n个元素,另一个作为临时存放数据用;
3)定义length,表示以三个一组(1,2,3),剩余的元素个数;
4)将剩余个数按顺序存放到临时数组中,再将原数组中(下标+1是3的倍数的)以外的元素接着原来剩余的元素后方存放;
5)将原数组清空,全部赋为0,再将临时数组中的所有元素复制到原数组中,重复执行3)、4)、5),直到剩余三个;
下面是我自己写的代码,冗长,还望高人赐教!
#include <stdio.h>
void print(int m)
{
int a[1000];
int temp[1000];
int d, length; //length 保存以三个一组剩余的元素个数
for(d = 0;d < m;d++) //先对原数组进行初始化,利用数值0~n-1表示原来的下标
{
a[d] = d + 1;
}
if(m <= 3)
{
printf("最后一个数的原下标为:%d\n",a[1] - 1);
}
else if(m>3)
{
while(m > 3)
{
int i, j, k, l;
length = m % 3;
if(length == 1)
{
temp[0] = a[m-1];
for(j = 0,k = 0; j < m - 1,k <= m - 1; j++,k++)
{
if((k + 1) % 3 != 0)
temp[j + 1] = a[k];
if((k + 1) % 3 == 0)
{
k++;
temp[j] = a[k];
}
}
for(l = 0;l < m;l++)
{
a[l] = 0;
}
for(i = 0;i < ( m - m / 3);i++)
{
a[i] = temp[i];
temp[i] = 0;
}
}
else if(length == 2)
{
temp[0] = a[m-2];
temp[1] = a[m-1];
for(j = 0,k = 0; j < m - 2,k < m -2; j++,k++)
{
if((k + 1) % 3 != 0)
temp[j + 2] = a[k];
if((k + 1) % 3 == 0)
{
k++;
temp[j + 2] = a[k];
}
}
for(l = 0;l < m;l++)
{
a[l] = 0;
}
for(i = 0;i < ( m - m / 3);i++)
{
a[i] = temp[i];
temp[i] = 0;
}
}
else
{
for(j = 0,k = 0; j < m,k < m; j++,k++)
{
if((k + 1) % 3 != 0)
temp[j] = a[k];
if((k + 1) % 3 == 0)
{
k++;
temp[j] = a[k];
}
}
for(l = 0;l < m;l++)
{
a[l] = 0;
}
for(i = 0;i < ( m - m / 3);i++)
{
a[i] = temp[i];
temp[i] = 0;
}
}
m = m - m / 3;
if(m == 3)
printf("最后一个数的原下标为:%d\n",a[1]-1);
}
}
}
int main()
{
int num;
printf("Please input a number:");
scanf("%d",&num);
print(num);
return 0;
}