一、问题描述
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; }