Data structure (ZKNU OJ) Monkey chooses the king (circular linked list solution method)

Description

There are m monkeys in a circle, numbered clockwise from 1 to m. Now I plan to choose a king from them. After negotiation, the rules for deciding to choose the king are as follows: start from the first to count clockwise, the monkeys who report to n go out of the circle, and then from the next to count clockwise from 1, ..., and so on, the last remaining Down is the king.

Input

The first line is a positive integer T representing the number of groups of test data. There are T lines below, each line has two integers m and n, separated by a space, representing the number of monkeys and the number of reported n respectively. 1≤m≤100, 1≤n≤200.

Output

Each set of data has an output corresponding to the number of the king.

Sample Input

1
3 2

Sample Output

3

Obviously, this is again a classic Joseph ring problem.

There are many solutions to the Joseph ring, and there are many excellent solution codes on the Internet. The following is just a personal problem-solving understanding and is for reference only.

Circular Linked List--Solving the Joseph Ring Problem

        *The first thing to pay attention to is to establish a linked list. According to the method taught by the teacher in class, the head node is followed by the data virtual node, and then the data element node.

           

                         *The picture comes from Mr. Wang Hongfeng's courseware

But considering two places, one is that the head node of the linked list used in this question does not need to store information about the linked list, so the data node can be used as the head node, and there is no need to define a special head node structure type; the second is that this solution is a circular linked list, To save time (mainly because I'm lazy!--). Therefore, I directly use the virtual data node as the head node, and the data type of the head node is not specifically defined, so pay attention when reading the code.

Problem solving ideas:

       1. Create a linked list, number each node of the linked list, and after reading the data, the tail node pointer field points to the first data node, forming a circular linked list

       2. Traverse the linked list and count, when the count reaches n-1, delete the next node and clear the count. This cycle is repeated until there is only one node left (that is, when the data of two adjacent nodes are equal), and the loop is jumped out.

       3. The pointer brings back the last remaining data and prints it out.

The whole idea is very simple, the key is that the construction of the circular linked list cannot go wrong!

Specific implementation code and detailed comments:

#include<stdio.h>
#include<malloc.h>
typedef struct LDataNode
{
	int number;
	struct LDataNode *next;
}LDataNode,*LinkList;
int InitList(LinkList *head);
int ListCreate(LinkList *head,int n);
int ListDelete(LinkList *head,int *flag);  
//initialization
int InitList(LinkList *head)
{
	*head = (LinkList)malloc(sizeof(LDataNode));
	if(*head == NULL)
	{
		return -1; // memory allocation failed
	}		
	(*head)->next = NULL;
	return 0;
}
// read data
int ListCreate(LinkList *head,int n)
{
	// principle of tail insertion
	LinkList rear=(LinkList)malloc(sizeof(LDataNode));
	rear=*head;
	for(int i=1;i<=n;i++)//Number enters the linked list
	{
		LinkList p=(LinkList)malloc(sizeof(LDataNode));
		p->next=rear->next;
		p->number=i;
		rear->next=p;
		rear=p;
	}
	rear->next=(*head)->next;//This step is the key point, build a loop! !
}
// delete node
int ListDelete(LinkList *p,int *flag)//flag brings back the deleted data, backup
{
	if((*p)->next->number==(*p)->number)//The data of two adjacent nodes are the same
	{
		*flag=(*p)->number;//Indicates that there is only one node left
		return 1;
	}
	// delete operation
	*flag=(*p)->next->number;		
	LDataNode *q = (*p)->next->next;
    (*p)->next=q;
	return 0;
}
intmain()
{
	int T,m,n;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&m,&n);
		LinkList head;
		InitList(&head);
		ListCreate(&head,m);
		LDataNode *p=(LDataNode *)malloc(sizeof(LDataNode));
		p=head;
		int count=0,x;
		while(1)
		{
			p=p->next;
			count++;//count
			if(count==n-1)
			{
				count=0;
				// delete the nth node
				int flag=ListDelete(&p,&x);
				if(flag)
				{
					break;
				}
			}
		}
		printf("%d\n",x);
	}
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325488735&siteId=291194637