一、问题描述
n个数字,[0,n-1],连成环,从第1个数开始,找到第m个数,删除,然后从删除后的下一个数开始继续数第m个数删除,问最后剩下哪个数二、解法
1、通过设定状态标志位,(声明一个状态数组status[N],status[i]==0时表示未出圈,出圈时将对应第i号人的status置为出圈的次数;即status[i]=count)2、循环条件是:当count值在N范围内,则循环;
3、最后剩下的数就是status数组状态值仍为0的下标对应的数。
三、C代码
/*******************************************************
Author:tmw
date:2018-3-17
********************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int joseph( int* array, int array_len, int m )
{
int count = 0; //用于记录删除了多少个元素
int start = -1; //初始值若为0,则需要单独对第0个位置的元素计数,设为-1就囊括在死循环里了
/**状态标记数组,如果为0表示未被删除,非0表示已被删除**/
int status[array_len];
memset(status,0,sizeof(status));
while( count<array_len-1 )
{
int i = 0;
while(1)
{
/**从标记数组的下一位开始计数**/
start = (start+1)%array_len;
if( status[start] == 0 )
i++;
/**
当数到第m个数时,array[i]出列---即:该位置状态值非0,
且出列count++,并且跳出循环,重新再从0数到m
**/
if( i == m )
{
count++;
status[start] = count;
break;
}
}
}
/**找到状态值为0的下标,并返回对应的值**/
int k = 0;
while( k<array_len )
{
if( status[k] == 0 )
break;
k++;
}
printf("最后剩下的元素位置为:%d 值为:%d\n",k,array[k]);
// int i;
// for( i=0; i<array_len; i++ )
// printf("%d ",status[i]);
// printf("\n");
return array[k];
}
四、测试代码及结果
int main()
{
printf("测试代码\n");
int array1[10] = {1,2,3,4,5,6,7,8,9,10};
joseph(array1,10,4);
int array2[20] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
joseph(array2,20,2);
return 0;
}