这道题我想了半个小时,对于没有接触过科班教育的我之前根本不知道这是经典约瑟夫问题,但是再难的题,我深信只要普通人能解,计算机就一定能解决,于是,我把问题完全转化为普通的算法,硬刚,难点仅仅在于把人类语言转化为c语言而已。于是我想到了用结构体进行解题。代码如下:
void CountOff(int n, int m, int out[])
{
int i, j, k;
struct abc
{
int flag;
int data;
}A[100000]; // 用flag去判断这个人退出没, data记录顺序
for(i = 0; i < n; i++)
{
A[i].flag = 0;
A[i].data = 0;
} // 初始化
int cnt = 1; // 退出的顺序记号
i = 0; j = 0; k = 0;
while(cnt != n+1)
{
if(j == 0) // 第一次要特判
{
i += m-1;
j = 1;
A[i].data = cnt;
A[i].flag = 1;
cnt++;
}
else
{
for(k = 0; k < m; k++)
{
i++;
if(i > n-1) // 每次加法后都要判断是否越界,模拟循环
{
i = (i % (n-1)) - 1;
}
while(A[i].flag == 1) //模仿筛选的过程
{
i++;
if(i > n-1) //例行循环
{
i = (i % (n-1)) - 1;
}
}
}
while(A[i].data != 0) // 相当于发现空位置,就插
{
i++;
if(i > n - 1) //例行循环
{
i = (i % (n-1)) - 1;
}
}
A[i].data = cnt;
A[i].flag = 1;
cnt++;
}
}
for(i = 0; i < n; i++) out[i] = A[i].data;
return;
}