使用循环链表实现 “猴子选大王”

题目:猴子选大王,现有n个猴子,一开始从第k个猴子开始从1开始报数,报到t的猴子会被淘汰,然后又从它的下一个猴子从1开始报数,如此循环,一直到只剩下一个猴子,这个猴子就是大王了,求得每次被淘汰猴子的编号及最后选出的猴大王编号。

#include<stdio.h>
#include<stdlib.h>

typedef struct ListNode node;

struct ListNode{
    
    
	  int data;//编号 
	  node* next;  
}; 

typedef struct LinkQueue{
    
    
	node* front;
	node* rear;
} Queue;

Queue* Build(Queue* S, int Data)//构建结构 
{
    
    
	if(S->rear == NULL){
    
    
	    node* p = (node* )malloc(sizeof(node));
		S->front->next = p; 
		S->rear = p;
		p->next = NULL;
		p->data = Data; 	
	    return S;
	}else{
    
    
        node* p = (node* )malloc(sizeof(node));
        S->rear->next = p; 
		S->rear = p;
	    p->data = Data;
	    p->next = NULL;
	    return S;
	}
}

void Solution(Queue* S, int k, int t, int n)//解决问题 
{
    
    //从第K个猴子开始  报到 t的猴子会被淘汰 
	node* p= S->front->next;//空节点的下一个
	node* p2 = S->front;//作用是跟在P的后面,便于删除节点 
	/*因为p2永远跟在p后,而消除的永远是p指向的节点,因此
	最后剩下的只有p2指向的节点*/ 
	int frist = k; 
	int death = t;
	int num = 1;
    
    if(frist==1&&death==1){
    
    
    	while(p!=S->rear){
    
    
	    	printf("\n被淘汰猴子的编号为:%5d\n", p->data);
			p = p->next; 
	    }
		printf("\n\n\n猴子大王的编号为:%5d\t", p->data);
    }
	for(int i=2; i<=frist; i++){
    
    
		 p = p->next;
		 p2 = p2->next;
	}//此时P到了第K个 
	//因为p2必须进入循环体,所以frist,death两者不能都为1 

	while(p!=p2&&p&&(frist!=1||death!=1)){
    
    
	    while(num==death&&p&&n!=1){
    
    
            node* h = p;
            printf("\n被淘汰猴子的编号为:%5d\n", h->data);
			p2->next =  p2->next->next;
			p = p2->next;
			h->next = NULL;
			free(h); 
			num = 1;
			--n;
  		}
        p = p->next;
        p2 = p2->next;
        ++num;//继续报数   
	} 
	if(p2&&(frist!=1||death!=1)){
    
    
      printf("\n\n\n猴子大王的编号为:%5d\t", p2->data);	
	}
    
}

int main()
{
    
    
	 //构建循环结构 
	 Queue* S = (Queue* )malloc(sizeof(Queue));//存放头尾指针 
	 node* head = (node* )malloc(sizeof(node));//头节点 
	 head->next = NULL; 
	 S->front = head;
	 S->rear = NULL;
     /*如果只有1个猴子,那么没有选择的必要
	   因此一定大于1*/
	 int n, i, Data;//n个猴子且n不为1 
     printf("n = \t");
     scanf("%d" ,&n);
 	 while(n <= 1){
    
    
 	 	 printf("输入猴子数过小,请重新选择:\n");
 		 printf("n = \t");
         scanf("%d" ,&n);
 	 } 
	 
	 i = n; 
     while(i--){
    
    
    	 printf("\n输入编号:\t");
     	 scanf("%d" ,&Data);
     	 S = Build(S, Data);
     }
	 S->rear->next = S->front->next;//首尾相连
	 //循环结构建立完成
	 //接下来到了计算阶段
	 int k, t; 
	 printf("\n从第几个猴子开始?:\t");
	 scanf("%d", &k); 
	 printf("\n报到几的猴子会被淘汰?:\t");
	 scanf("%d", &t); 
	 
 	 if(k <= n&&t >= 1){
    
    
 		Solution( S, k, t, n);
 	 }else{
    
    
 	 	printf("\n输 入 错 误 !\n");
 	 }
	 
	 
} 

猜你喜欢

转载自blog.csdn.net/qq_52001969/article/details/113358883