Question link:
Http://uva.onlinejudge.org/index.php? Option = com_onlinejudge & Itemid = 8 & page = show_problem & problem = 69
Question meaning:
There are a total of n persons numbered 1-N, standing in a circle. The two civil servants start from 1 and start every K and m respectively in the clockwise direction, select the list of people who have obtained the application. If the two civil servants select the same person at the same time, only one output is used. Give priority to the selection list of the first civil servant. Because the selection is at the same time, when counting, if it happens to be selected by another civil servant, it should also be counted.
Solution:
Use a two-way linked list to simulate the selection process. Use the Count pointer (counter-clockwise) and the clock pointer (clockwise). If the Count pointer is selected, delete it from the linked list, use the selected number of people as the control condition for the end. For more information, see the program.
Code:
# Include <iostream> # include <cmath> # include <cstdio> # include <cstdlib> # include <string> # include <cstring> # include <algorithm> # include <vector> # include <map> # define EPS 1e-6 # define Inf (1 <20) # define PI ACOs (-1.0) using namespace STD; struct node {int data; struct node * Next, * pre ;}; int N; struct node * count, * clock; // note that clock cannot be used, which may be a conflict with the system void build () // create a bidirectional circular linked list {struct node * P; P = COUNT = clock = (struct node *) malloc (sizeof (struct node); // when there is only one element, clock also has a value, which is also a cyclic linked list count-> DATA = 1; count-> next = count-> pre = NULL; For (INT I = 2; I <= N; I ++) {clock = (struct node *) malloc (sizeof (struct node); clock-> DATA = I; clock-> next = NULL; clock-> pre = P; // bidirectional cyclic linked list p-> next = clock; P = clock;} clock-> next = count; count-> pre = clock; return;} void solve (int K, int m) {int flag = 0, num = 0; while (1) // use the number of outputs to control the end. It is relatively simple. If you use a single node to control the end, not uniform {for (INT I = 2; I <= K; I ++) Count = count-> next; For (INT I = 2; I <= m; I ++) Clock = clock-> pre; If (count-> DATA = clock-> data) // The two pointers point to one place at the same time, output only one {If (num = N-1) // judge the end {printf ("% 3d \ n", Count-> data); flag = 1 ;} else {printf ("% 3d,", Count-> data); // note that the three characters are num ++;} COUNT = count-> next; clock = clock-> pre; free (clock-> next); If (flag = 1) return; clock-> next = count; // Delete this node count-> pre = clock;} else {If (num = n-2) {printf ("% 3d % 3d \ n", Count-> data, clock-> data); flag = 1;} else {printf ("% 3d % 3d,", Count-> data, clock-> data); num + = 2 ;} (count-> next)-> pre = count-> pre; // Delete the Count node (count-> pre)-> next = count-> next; struct node * temp = count; Count = count-> next; free (temp); If (flag = 1) return; (clock-> next) -> pre = clock-> pre; // delete a clock node (clock-> pre)-> next = clock-> next; temp = clock; clock = clock-> pre; if (COUNT = temp) // note that the current pointer is moved to the position where the pointer is to be deleted, Count = temp-> next; free (temp) ;}} return ;} int main () {int K, M; while (scanf ("% d", & N, & K, & M) & N + K + M) {build (); solve (K, M) ;}return 0 ;}