其实就是“猴子选大王”的另一个版本,先粘贴上代码
# include<stdio.h> # include<stdlib.h> typedef struct Node { int data; struct Node * nextPtr; }NODE; typedef NODE * NODEPTR; NODE * createNode(int n); void DelList(NODEPTR prev); NODEPTR Garrison(NODEPTR headPtr,int x,int y); int main() { int n = 0, i = 0, j = 0; NODEPTR headPtr=NULL; scanf("%d",&n); for(i = 1;i<=n;i++) { for(j = 1;j<=n;j++) { headPtr=createNode(n); headPtr=Garrison(headPtr,i,j); if(headPtr->data==1)//输出在士兵数为n时满足要求的x,y { printf("When there are %d soldiers , it starts from %d and 'y' is %d.\n",n,i,j); } free(headPtr); } } return 0; } NODE * createNode(int n) { NODEPTR headptr = NULL, curptr = NULL,preptr = NULL; int num = 1; while (num<=n) { //对n个成员进行创建链表并编号 curptr = (NODEPTR)malloc(sizeof(NODE)); curptr->data = num; if(preptr != NULL) { preptr->nextPtr = curptr; } preptr = curptr; if(headptr == NULL) { headptr = curptr; } num++; } curptr->nextPtr = headptr;//进行首尾链接 return headptr; } NODEPTR Garrison(NODEPTR headPtr,int x,int y){ NODEPTR prev = NULL; int i = 0; while (headPtr->nextPtr->data != x)//进行遍历,直到指针的下一个节点的编号为x { headPtr = headPtr->nextPtr; } while (headPtr != headPtr->nextPtr) {//循环直到只剩下一个节点 for (i = 1; i <= y; i++) { prev = headPtr; headPtr = headPtr->nextPtr; } DelList(prev); headPtr = prev; } headPtr->nextPtr = NULL;//将无限循环单节点链表断开 return headPtr; } void DelList(NODEPTR prev)//在一位士兵被点到后删除该节点 { NODEPTR curptr = prev->nextPtr; prev->nextPtr = curptr->nextPtr; free(curptr); }不过多解释,其中有详细的注释