问题描述:
在《josephus Problem 初级(使用数组)》中,我们提出了一种最简单直接的解决方案。
但是,仔细审视代码之后,发现此种方案的效率并不高,具体体现在,当有人出局时,遍历数组仍需要对其进行判断,
这无疑做了无用功,降低了代码效率,在人数多时尤其明显。
解决方案:
当有人出局时,考虑将当前出局的人的前一个人(未出局)的下一个人置为当前出局的下一个人(未出局)。这样,便确保了每次对counter的增加都是有效的,遍历到的人都是还没有出局的。大大提升了程序的效率。这其实运用了链表的思想。
代码:
#include <stdio.h> /*total people number*/ #define ALL 100 /*people leave when count to left_counter*/ #define left_counter 3 /*next Array record the next people's position*/ int next[ALL]; /*init next array*/ void initNext() { int i = 0 ; for (i = 0; i < ALL; i++) { next[i] = (i+1) % ALL; } } /*print next array*/ void printNext() { int i = 0; for (i = 0; i < ALL; i++) { printf("%d ", next[i]); } printf("\n"); } int main(void) { initNext(); int left = ALL; /*init total left number*/ int counter = 0; /*init counter*/ int i = 0; /*init array index*/ int prev = All-1; /*init prev*/ while (left > 0) { counter++; /*if counter == left_counter , people out, set next[prev] = next[i] counter = 0 left-- **/ if (counter == left_counter) { left--; printf("%d is out\n", i+1); counter = 0; next[prev] = next[i]; printNext(); } /*change prev, increase index*/ prev = i; i = next[i]; } printf("problem finished!\n"); return 0; }
时间: 2024-10-13 16:21:14