Description
Input
Output
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); } }